OpenXRランタイムを実行時に選ぶ
はじめに
XRアプリを開発する時は各デバイス毎のSDKを利用する必要がありマルチデバイス対応するのは非常に面倒でした。そのためどのXRデバイスでも動作する共通規格としてKhronosグループでOpenXRを策定しています。現状OpenXRを実装したWindowsのランタイムは以下の5つがあります。
- Oculus
- SteamVR
- WindowsMR
- Vive
- Varjo
これらをインストールするとどれか1つをアクティブにできますがアプリ側から容易に選択することができませんでした。そこでOpenXR 1.0.18からランタイム一覧を列挙される仕様が追加されたのでそれを利用する方法を解説します。
ちなみにこの内容はOpenXRの仕様なのでUnity以外でも利用できます。
アクティブなOpenXRランタイム
各ランタイムは以下の設定画面からアクティブ化できます。
Oculus
SteamVR
WindowsMR
Vive
Varjo
ここでアクティブにすると以下のレジストリにjsonファイルのパスが保存されます。
- レジストリ
HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenXR\<major_api_version>
キーにEXPAND_SZでActiveRuntime
-
<major_api_version>
は現状1
のみです。
-
Oculusがアクティブだと以下のようになります。
そしてOpenXR SDKは以下の順序でランタイムを探索します。
- 環境変数
XR_RUNTIME_JSON
- 上記のレジストリキー
Unityエディタからは環境変数を利用して以下の設定からランタイムを切り替えられます。
という事はアプリも環境変数にランタイムのjsonパスを設定してからOpenXRをアクティブにすれば切り替えられそうです。
インストール済みのOpenXRランタイム一覧 (OpenXR 1.0.17以前)
各ランタイムのjsonパスはそれぞれのインストール先に配置されています。ですがインストールパスを変更できるのでレジストリなどからパスを決定する必要がありとても面倒です。デフォルトのパスにインストールするとjsonはそれぞれ以下のパスに存在します。
- Oculus
C:\Program Files\Oculus\Support\oculus-runtime\oculus_openxr_64.json
- SteamVR
C:\Program Files (x86)\Steam\steamapps\common\SteamVR\steamxr_win64.json
- WindowsMR
C:\WINDOWS\system32\MixedRealityRuntime.json
- Vive
C:\Program Files (x86)\VIVE\Updater\App\ViveVRRuntime\ViveVR_openxr\ViveOpenXR.json
- Varjo
C:\Program Files\Varjo\varjo-openxr\VarjoOpenXR.json
インストール済みのOpenXRランタイム一覧 (OpenXR 1.0.18以降)
各ランタイムのjsonは配置場所が規格化されておらずランタイム自体もインストール先を変更できるのでパスを探すのが面倒でした。
そのためOpenXR 1.0.18からランタイムのjsonパスを登録するレジストリキーが以下のように定めされました。
- レジストリ
HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenXR\<major_api_version>\AvailableRuntimes
キーにDWORDで名前がjsonパス、値0
なら有効、0
以外なら無効
それぞれのランタイムについて以下のバージョンで確認しましたがOculusとVarjoしか対応していないため他も追従してほしい所です。
- Oculus: 35.0.0.73.175
- SteamVR: 1.12.4
- WindowsMR: 109.2111.23003.0
- Vive: 2.0.18.6
- Varjo: 3.4.0.8
Unityでランタイムを指定してOpenXRを有効にする
上述の仕様を元にPC内に存在するjsonパス収集と環境変数にjsonパスを設定するライブラリを作りました。
これを利用するとランタイムを指定してOpenXRアプリを実行できるようになります。
jsonパス収集はレジストリから探索する方法と1.0.18のレジストリキーから収集する方法の2つを用意しています。
これを利用してOculusランタイムがあれば優先した後にVRを有効にする場合は以下のコードになります。
スクリプトからVRを有効にするのでProject Settings/XR Plug-in ManagementのInitialize XR on Startupを無効にしておきます。
using OpenXRRuntimeJsons;
public class Initialize : MonoBehaviour
{
private void Awake()
{
// PCに存在するランタイムのjsonパスを収集してOculusが存在するなら環境変数XR_RUNTIME_JSONに設定する
SetOculusRuntimeFromAvailableRuntimes();
// XRを初期化してOpenXRを有効にする
StartCoroutine(StartXRCoroutine());
}
private void SetOculusRuntimeFromAvailableRuntimes()
{
// Get the available OpenXR runtime json
IReadOnlyDictionary<OpenXRRuntimeType,string> openXRRuntimes = OpenXRRuntimeJson.GetRuntimeJsonPaths();
if (openXRRuntimes.ContainsKey(OpenXRRuntimeType.Oculus))
{
// Use the Oculus OpenXR runtime
OpenXRRuntimeJson.SetRuntimeJsonPath(OpenXRRuntimeType.Oculus);
}
}
private IEnumerator StartXRCoroutine()
{
if (XRGeneralSettings.Instance.Manager.isInitializationComplete)
{
yield return true;
yield break;
}
Debug.Log("Initializing XR...");
yield return XRGeneralSettings.Instance.Manager.InitializeLoader();
if (!XRGeneralSettings.Instance.Manager.isInitializationComplete)
{
Debug.LogError("Initializing XR Failed. Check Editor or Player log for details.");
yield return false;
}
else
{
Debug.Log("Starting XR...");
XRGeneralSettings.Instance.Manager.StartSubsystems();
yield return true;
}
}
}
また、PC内に存在するランタイム名のボタンを列挙して選択できるサンプルプロジェクトも用意しました。
5つのランタイムがインストールされているPCでサンプルプロジェクトを実行すると以下のように環境変数、システムデフォルトのレジストリ、各ランタイムのボタンが表示されて押したランタイムを有効にしてOpenXRを利用したVRのシーンをロードします。
Discussion