Unity+Oculus Quest開発メモ

最終更新日:2020年02月08日

UnityでOculus Quest対応アプリを開発する方法やTipsをまとめています。

更新履歴

(2020年2月8日)「リフレッシュレートを変更するには」を追加
(2020年2月5日)「OVR Scene Quick Preview」の項目を追加
(2020年2月2日)「パフォーマンス・チューニング」をいくらか書き足し。全体の構成を大幅に整理
(2020年1月20日)Oculus Integraion 12.0にあわせて更新、「パフォーマンス・チューニング」を作成


UnityでOculus Quest対応アプリを作るには

UnityのOculus Quest対応の概要について

Unityは標準でOculus Questに対応しています。Oculus QuestはAndroidベースですので、プラットフォームをAndroidにしてVRサポートを有効するとOculus Questで動作するアプリをビルドできます。

さらに、Oculus QuestやOculusプラットフォーム固有の機能を使用する場合は、Asset StoreにあるOculus IntegrationをインポートしてMain CameraをOVRCameraRigプレハブに入れ替えます。基本的にはOculus Integrationを使用します。

Compatibility and Version RequirementsのページでサポートしているUnityのバージョンを確認できます。

Oculus Questを開発者モードにする

Oculus Questで自作のアプリが動くようにするには、「開発者モード」にする必要があります。スマートフォンにインストールしたOculusアプリの右下の「設定」をタップし、接続されているOculus Questをタップで開いて「その他の設定」をタップすると「開発者モード」が出てきますのでオンにしてください。

PCにUSBケーブルで接続すると、Oculus Questの画面に「USBデバッグを許可しますか?」というダイアログが開きますので許可します。

Oculus Questアプリをビルドするには

Oculus QuestはAndroidベースですので、UnityのAndroidビルドを使用します。

Unity で新規プロジェクトを作成したら、以下の手順を行います。

  • Build SettingsでプラットフォームをAndroidに変更する
  • Build SettingsのTexture Compression(テクスチャの圧縮方式)をASTCに変更する
  • Player Settings… でGraphics APIsのVulkanを削除する
  • Player Settings… で、Minimum API Levelを「Android 6.0 ‘Marshmallow’ (API level 23)」に変更する
  • Package Nameの「com.Company.ProductName」のCompanyとProductNameを適当な組織名とプロダクト名で書き換える
  • XR Settingsにある「Virtual Reality Supported」をチェックして、右下の+ボタンを押してOculusを追加する
  • Asset StoreにあるOculus Integrationをインポート(OVRPlugin 等をアップデートするダイヤログが出たら従う)。まるごとインポートすると、インポートやビルドがめちゃくちゃ遅いです。特に必要なければOculus/VR以下だけをインポートすると速いです。

Projectビューの Oculus/VR/Scenes/Room シーンを開いて、Build Settingsを開き、プロジェクト初期状態のSample Sceneを削除してAdd Open Scenesで入れ替えてください。

Oculus Questを接続して、Build SettingsウィンドウでBuild and Runボタンを押し、適当な.apkファイル名を指定してビルド・実機に転送します。初回ビルド時にCompiling shader variantsでOVR Avatar関連の多数のシェーダーのビルドが走りますが、2度目以降はキャッシュされます。成功するとアプリが起動し、コントローラーのサムスティックで移動や回転ができます。

実機に転送したアプリは、Oculus Questの ライブラリ > 提供元不明のアプリ に格納され、いつでも実行できます。

動かない場合は

UnityのPlayer SettingsのXR Settingsにある「Virtual Reality Supported」がオンになっているか、またVirtual Reality SDKsでOculusが有効になっているか確認してください。

エディタで簡単に開発するには

Oculus IntegrationはRiftやHTC Viveに対応しています。それらPCヘッドセットがあるとEditorで再生して実行できるため開発が楽になります。


プロジェクト設定について

グラフィックス設定

フォワードレンダリングにして、Quality SettingsでAnti Aliasingを2xか4xのMulti Samplingに設定するのが基本になりそうです。ほか、

  • Single-Pass Stereoレンダリングにする
  • Dynamic BatchingとStatic Batchingをオンにする(Graphics Jobsは使わないこと)

が基本設定として推奨されています。また,リニアカラーに対応しています。

ほかこちらのページがとても参考になります。

ビルド設定

Oculus Storeにアプリを提出する場合はScripting BackendをIL2CPPにしてARM64でビルドする必要があります。が、IL2CPPはビルドが重すぎるので、開発中や、個人作品ではMonoでいいかもしれません。

アプリの管理について

ビルド・転送したアプリをアンインストールするには

下記adbコマンドを実行します。

$ adb uninstall [パッケージ名]

パッケージ名は、Questの「提供元不明のアプリ」で確認したり、下記コマンドで一覧表示することもできます。

インストールされているアプリの一覧を表示するには

$ adb shell cmd package list packages

デバッグに使えるツール

Android Logcatパッケージ

UnityからAndroidのログ出力(adb logcatコマンド)を簡単に閲覧できるウィンドウです。Unityのパッケージマネージャーからインストールします(previewパッケージです)。Build and Runすると自動的にデバイスに接続してログが表示されます。キーワードでフィルタをかけたり、スクリーンショットを撮ることもできます。

OVR Scene Quick Preview

Oculus Integraionに含まれているツールで、Questでアプリを実行したままでシーンを更新できるツールです。簡単な実験シーンを更新して試したり、負荷を比較したりするのに使用できます。

使用方法は以下の通りです。

  • あらかじめBuild Settingsでシーンを登録しておく
  • Oculus > OVR Build > OVR Scene Quick Preview メニューでウィンドウを開く
  • 「Build and Deploy App」で転送用のアプリをビルド・起動する
  • 「Build and Deploy Scene(s)」を押すとQuestのシーンが更新される

パフォーマンス・チューニング

Questのハードウェアについて

ハードウェア詳細の解説がOculusのブログの下記エントリにあります。

QuestはSnapdragon 835を搭載しています。CPUは8コアで、4つがlarge core、4つがsmall coreです。アプリの実行に割り当てられているのは3つのlarge coreで、残りの1つのlarge coreはタイムワープとシステムサービスに、4つのsmall coreはトラッキングやその他のシステムソフトウェアに使用されているとのことです。

下記で紹介するツールの多くはCPUのコアごとの使用率を確認できないため注意が必要です(100%行ってないのになんで処理落ちするんだってなる)。

GPUはSnapdragon 835に統合されているAdreno 540ですが、多くのモバイルGPU同様タイルベースレンダリングであることに注意が必要です。Qualcommのサイトのドキュメント「Adreno Vulkan Developer Guide」にチューニングのTipsが載っています。

CPU・GPUレベルについて

Questでは負荷によってCPU・GPUレベルという形でクロック数が変動します。現在のレベルはOVR Metrics ToolやOculus Profilerで確認できます。クロック数によってCPU・GPUの使用率が変動するため、パフォーマンス・チューニングのときはOculus Integrationの下記APIでレベル4に固定しておいたほうが数値が分かりやすいかもしれません。

OVRManager.cpuLevel = 4;
OVRManager.gpuLevel = 4;

パフォーマンス・チューニングに使用できるツール

Oculus Questのパフォーマンス最適化に使用できる主なツールを列挙します。

OVR Metrics Tool

CPU使用率やGPU使用率等のグラフ・数値をヘッドセット内でオーバーレイ表示できます。どんなシチュエーションで重くなるか、簡易的なパフォーマンスの測定に便利です。

下記ページからダウンロードできる.apkファイルを adb install でインストールしてQuestで起動し、表示を有効にして「BASIC」あたりを選択してください。Questの再起動が必要な場合があります。

ドキュメントは下記ページにあります。

Unityのプロファイラー

Quest実機に対して、Unityのプロファイラーが使用できます。Build SettingsでDevelopment Buildをチェックした上でビルド・実行して、プロファイラを開き、プロファイラ上部の"Playmode"と表示されているところを"AndroidPlayer"に変更してください。

CPUモジュールでTimelineを表示すると、フレームごとの処理の詳細が追いかけやすいです。

なおGPUのモジュールを有効にしているとプロファイラーのクエリ待ちでフレームレートが低下しますので注意してください。

RenderDoc

Quest実機に対して使用できるオープンソースのフレームデバッガです。Oculusのブログに使い方が詳しいです。描画コールごとの処理時間を計測表示できますが、タイルベースレンダリングなので参考程度にとのことです。

Snapdragon Profiler

Qualcommの公式ツールです(Qualcommの開発者アカウント作成が必要)。Snapdragonの各種メトリクスを詳細表示できます。特に、SnapdragonのCPU各コアごとの使用率や、タイルベースレンダリングのタイル数等も見ることができます。

Oculus Profiler

Oculus Integrationに含まれているツールです。

アプリをBuild and RunしてUnityの Oculus > Tools > Oculus Profile Panel メニューで開きます。CPU・GPUレベルとCPUのコアの平均使用率、最も負荷がかかっているコアの使用率が確認できます。PCとQuestが同一ネットワーク内にある必要があります。

Fixed Foveated Rendering

Fixed Foveated Renderingは、視野の中心部のみを高解像度で描画し、ピクセル描画負荷を減らすOculus固有の機能です。設定の変更方法です。

OVRManager.fixedFoveatedRenderingLevel = OVRManager.FixedFoveatedRenderingLevel.{High/HighTop/Low/Medium/Off};

タイルベースレンダリングで視野の端の方のタイルの描画解像度を下げることによって、ピクセル描画負荷の重いアプリで描画が25%程度軽量化されるとのことです。シンプルなシェーダのアプリやGPUバウンドになっていないアプリでは恩恵を受けられません。詳細の解説がこちらにあります。

運用Tips

ガーディアンの表示を切るには

Questの Settings > See All > Developer > Guardian でガーディアンの表示を切ることができます。安全のため警告メッセージが表示されます。一度スリープすると元に戻ってしまうので、イベント展示等ではスリープ時間を最長の15分にしておくといいでしょう。

ヘッドセット内の映像をPCで表示するには

srccpyを使うのがおすすめです。なお、左右似画面の樽型表示になります。

その他のTips

過去のバージョンのOculus Integrationを参照するには

Oculus Integrationのリリースノートのページと、ダウンロードのページは、バージョン番号のところがプルダウンメニューになっていて、過去のバージョンが参照できます。

QuestのIPアドレスを確認するには

$ adb shell ifconfig

リフレッシュレートを変更するには

Questのリフレッシュレートは72Hzですが、以下で60Hzに変更できます。

OVRManager.display.displayFrequency = 60f;

72Hzでは負荷が少しオーバーしてしまうような場合に使用できるかもしれません。ただし、明るいシーンだと、おそらくパネルの黒挿入のため視界が非常にちらついて実用には耐えなさそうな感じでした。

位置トラッキングをリセットするには

コントローラーのトリガーを引くと位置トラッキングをリセットするサンプルスクリプトです。OVRInputを使っているので、OVRCameraRigが必要です。

using UnityEngine;

public class Recenterer : MonoBehaviour
{
    void Update()
    {
        if (OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger))
        {
            OVRManager.display.RecenterPose();
        }
    }
}

Oculus QuestではOculusボタンを長押しするとリセンターされるのでRiftと比べて使う機会は少ないかもしれません。

参考記事


参考リンク

書いた人:こりん(@korinVR
VR開発メモトップ