UnityでOculus Quest2開発入門 (入門編1)
こんにちは。たつぷり(@Tatsupuri2)です。シリーズ「UnityでOculus Quest2開発入門」の第2回目です。今回は、とりあえず動作を確認するために、箱をシーンに配置してビルドしてみます。その過程で、エミュレーターがうまく動かない現象が起きたので、その対処法についても書きます。
Oculus固有の機能をUnityで使うにはOculus Integrationを用いる。使い方は以下にまとめられている。
以下では、箱を配置しただけのシーンをビルドして実機で動かすまでの過程をまとめる。
テスト用で以下のようなUnityプロジェクトを作成した。ただ箱が並んでいるだけのシーンである。
Camera Rig
まず、デフォルトのMain Cameraを削除してOVRCameraRig
のプレハブに入れ替える。OVRCameraRig
を導入すると、HMDの動きを自動でトラックしてシーン内のカメラに反映させることができる。Camera Rigに関してのレファレンスは以下のURLである。
なお、Camera Rigには子のオブジェクトにTrakicking Spaceが用意されており、その中に手や目線についてのアンカーが用意されている。つまりコントローラーの位置を取得したりするのはCamera Rigを導入していればできる。
Build
Oculusの実機に転送する際はUSBケーブルでつないでおく必要がある。UnityからOculusをターゲットにしてビルドを試みたら、いくつか問題が起きたのでまとめておく。
Build Settingでは、レファレンスを参照して以下のようにした。 Buildを押すと単純にapkファイルを生成し、指定した場所に保存するだけである。 USBでつないだ実機に転送して実行するには、Build And Run を実行する必要がある。
この場合、Oculusの内部に実行ファイルを保存するわけではないので、一時的に実機で動かしているだけっぽい。 実行ファイルをOculusに保存するには別の方法が必要で、
Oculus Developper Hubを用いる方法(Oculus Developer Hub | Oculus Developers)
Android Debug Bridgeを用いる方法(Enable Device for Development and Testing | Oculus Developers)
がある。また、Build And Runを実行する以外にも、
- Oculus > OVRBuild > OVR Scene Quick Preview
- Oculus > OVRBuild > OVR Build APK And Run
を実行するという手段もある。テスト用のビルドに関しては、Oculus公式はこの方法でビルドすることを推奨している。
ビルドのエラー
今回、Build AndRunを実行すると以下のようなエラーがでた(OVR Scene Quick Previewなどで実機に転送したときはこのようなエラーは出なかった)。
この問題については以下の記事で議論されていた。
これによると、AndroidManifest.XML
に問題があったようである。これはTools > Oculus > Create store-compatible AndroidManifest.xml
で生成したファイルであるが、このファイルはアプリを公開するときに必要なものらしい。今回のケースのようにUnityからOculusに直接転送して動かす場合はこのファイルによってエラーが生じてしまう。このファイルを消したところ正常にビルドが通り実機に転送することができた。
実機に転送が完了してOculusでアプリが立ち上がったらケーブルを抜いても問題なかった。今回用意した箱を表示させるシーンをビルドしたら、配置された箱が見えてその周りを自由に歩くけることが確認できた。しゃがんだりするとそれに伴って目線が変わることも確認できた。
アプリを終了するときは、通常通りメニューを開いてアプリを終了させてホーム画面に戻ればよい。
Emulatorに関して
Oculus Integration ではUnity Editor上でHMDの動作を確認できるエミュレータが用意されている。しかし筆者の環境ではエミュレータが機能しなかった。その原因を考える。スクリプトを読んでみると、OVRHeadsetEmulator
クラスのOVRManagerinitialized
という変数がTrue
でないとエミュレーターが作動しないようだが、この変数の値を出力してみるとFalse
になっているため機能していなかったようだ。さらに読み進めると、この変数はOVRManager
クラス のInitOVRManager
メソッドが呼ばれるとTrue
になることが分かった。このメソッドは、OVRManager
クラスのAwake
中でOVRPlugin.initialized
がTrue
の時に呼ばれる。
そこで実際に、OVRPlugin
クラスのOVRPlugin.initialized
を見てみる。以下のそれを引用した。筆者はその詳細を理解しているわけではないが、OVRPLUGIN_UNSUPPORTED_PLATFORM
の時はFlaseを返すようになっているようだ。Unity Editor で動かしているときがOVRPLUGIN_UNSUPPORTED_PLATFORMに相当するのだと考えられる。
public static bool initialized { get { #if OVRPLUGIN_UNSUPPORTED_PLATFORM return false; #else return OVRP_1_1_0.ovrp_GetInitialized() == OVRPlugin.Bool.True; #endif } }
なので、以上のコードから
if (OVRPlugin.initialized) InitOVRManager();
の部分を
if (!OVRPlugin.initialized) InitOVRManager();
にすれば対処療法的だが動くはずだと考えられる。実際にやってみるとエミュレータを正しく使うことができた。この問題に関して調べてみたところ以下の記事でも似たようなことが議論されていた。