たつぷりの調査報告書

博士後期課程(理学)の学生が趣味でUnityやBlenderで遊ぶブログです。素人が独学で勉強した際の忘備録です。

UnityでOculus Quest2開発入門 (入門編1)

こんにちは。たつぷり(@Tatsupuri2)です。シリーズ「UnityでOculus Quest2開発入門」の第2回目です。今回は、とりあえず動作を確認するために、箱をシーンに配置してビルドしてみます。その過程で、エミュレーターがうまく動かない現象が起きたので、その対処法についても書きます。

Oculus固有の機能をUnityで使うにはOculus Integrationを用いる。使い方は以下にまとめられている。

developer.oculus.com

以下では、箱を配置しただけのシーンをビルドして実機で動かすまでの過程をまとめる。

テスト用で以下のようなUnityプロジェクトを作成した。ただ箱が並んでいるだけのシーンである。

f:id:Tatsupuri:20201202130832p:plain

Camera Rig

まず、デフォルトのMain Cameraを削除してOVRCameraRigのプレハブに入れ替える。OVRCameraRigを導入すると、HMDの動きを自動でトラックしてシーン内のカメラに反映させることができる。Camera Rigに関してのレファレンスは以下のURLである。

developer.oculus.com

なお、Camera Rigには子のオブジェクトにTrakicking Spaceが用意されており、その中に手や目線についてのアンカーが用意されている。つまりコントローラーの位置を取得したりするのはCamera Rigを導入していればできる。

Build

Oculusの実機に転送する際はUSBケーブルでつないでおく必要がある。UnityからOculusをターゲットにしてビルドを試みたら、いくつか問題が起きたのでまとめておく。

Build Settingでは、レファレンスを参照して以下のようにした。 f:id:Tatsupuri:20201202130820p:plainBuildを押すと単純にapkファイルを生成し、指定した場所に保存するだけである。 USBでつないだ実機に転送して実行するには、Build And Run を実行する必要がある。

この場合、Oculusの内部に実行ファイルを保存するわけではないので、一時的に実機で動かしているだけっぽい。 実行ファイルをOculusに保存するには別の方法が必要で、

がある。また、Build And Runを実行する以外にも、

  • Oculus > OVRBuild > OVR Scene Quick Preview
  • Oculus > OVRBuild > OVR Build APK And Run

を実行するという手段もある。テスト用のビルドに関しては、Oculus公式はこの方法でビルドすることを推奨している

f:id:Tatsupuri:20201202130828p:plain

ビルドのエラー

今回、Build AndRunを実行すると以下のようなエラーがでた(OVR Scene Quick Previewなどで実機に転送したときはこのようなエラーは出なかった)。

f:id:Tatsupuri:20201202130825p:plain

この問題については以下の記事で議論されていた。

forum.unity.com

これによると、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.initializedTrueの時に呼ばれる。

そこで実際に、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();

にすれば対処療法的だが動くはずだと考えられる。実際にやってみるとエミュレータを正しく使うことができた。この問題に関して調べてみたところ以下の記事でも似たようなことが議論されていた。

forums.oculusvr.com