(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]



VRモードと非VRモード両対応のSteam向けゲームをUnityで作る方法とモードの切り替え方【Unity】【Steam】【VR】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 2019.4.9f1
SteamVR Unity Plugin - v2.3.2 (sdk 1.4.18)


はじめに

今回はVRと非VRの両方に対応したSteam用のゲームをUnityで開発する方法です。


なお、両対応や切り替えをどうやるかという話で、

簡単に両方に対応したゲームが作れるという話ではないのであしからず。


VRモードと非VRモード両対応

まず、UnityでSteamのVR対応する方法は以前記事にしているのでこちらを参照してください。



ただ問題なのが、↑でVR対応すると常にVRモードなので、

ゲームの起動と同時にSteamVRが起動してしまいます。


なので両対応する場合は基本的に最初は非VR状態にした方が良いと思います。

そしてその方法はProject Settingsにある

f:id:kan_kikuchi:20200910112804j:plain


XR SettingsのVirtual Reality SDKsの一番上にNoneを追加するだけです。

f:id:kan_kikuchi:20200910112942j:plain



VRモードへの切り替え

次にVRモードへの切り替え方法ですが、以下のような流れになります。

(場合によっては必要ない処理もあるかもしれません)

  1. OpenVRをロード
  2. UnityのXRSettingsを有効にする
  3. SteamVRを有効にする
  4. SteamVRのインスタンスが作られるのを待つ


そして、これらの処理を一気に行えるVRModeInitializerという物を作ってみました。

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.XR;

/// <summary>
/// VRモードへの切り替えを行うクラス
/// </summary>
public class VRModeSwitcher : MonoBehaviour {

  //切り替え後の処理
  private Action<string> _callback;

  //=================================================================================
  //切り替え
  //=================================================================================

  /// <summary>
  /// VRモードへの切り替えを開始
  /// </summary>
  public void Begin(Action<string> callback = null) {
    _callback = callback;
    StartCoroutine(Switch());
  }

  //切り替え
  private IEnumerator Switch() {
    //OpenVRをロードする
    XRSettings.LoadDeviceByName("OpenVR");
    yield return null;
 
    //UnityのXR(VR)を有効にする
    XRSettings.enabled = true;

    //SteamVRが有効になるまで待機
    while (!Valve.VR.SteamVR.enabled) {
      Valve.VR.SteamVR.enabled = true;
      yield return null;
    }
 
    //SteamVRのインスタンスが作られるまで待機
    while (Valve.VR.SteamVR.instance == null) {
      yield return null;
    }

    //接続されているデバイス名をコールバックで返して終了
    _callback?.Invoke(Valve.VR.SteamVR.instance.hmd_TrackingSystemName);
  }

}


なお、使い方は以下のようにVRModeSwitcherを作成し、Beginメソッドを実行するだけです。

var switcher = new GameObject("VRModeSwitcher");
switcher.AddComponent<VRModeSwitcher>().Begin((deviceName) => {
  Debug.Log($"VRモードへの切り替え完了。デバイス名 : {deviceName}");
  Object.Destroy(switcher);
});



非VRモードへの切り替え

最後に非VRモードへの切り替え方法ですが、VRモードの切り替えと逆の事をするだけですが、

こちらも切り替え処理を一気に行えるNonVRModeSwitcherという物を作ってみました。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;

/// <summary>
/// 非VRモードへの切り替えを行うクラス
/// </summary>
public class NonVRModeSwitcher : MonoBehaviour {

  //切り替え後の処理
  private Action _callback;

  //=================================================================================
  //切り替え
  //=================================================================================

  /// <summary>
  /// 非VRモードへの切り替えを開始
  /// </summary>
  public void Begin(Action callback = null) {
    _callback = callback;
    StartCoroutine(Switch());
  }

  //切り替え
  private IEnumerator Switch() {
    //Noneをロードする
    XRSettings.LoadDeviceByName("None");
    yield return null;
 
    //UnityのXR(VR)設定を無効にする
    XRSettings.enabled = false;

    //SteamVRが無効になるまで待機
    while (Valve.VR.SteamVR.enabled) {
      Valve.VR.SteamVR.enabled = false;
      yield return null;
    }
 
    //コールバックを実行して終了
    _callback?.Invoke();
  }

}


これも使い方は以下のようにNonVRModeSwitcherを作成し、Beginメソッドを実行するだけです。

var switcher = new GameObject("NonVRModeSwitcher");
switcher.AddComponent<NonVRModeSwitcher>().Begin(() => {
  Debug.Log($"非VRモードへの切り替え完了");
  Object.Destroy(switcher);
});