Unity + Oculus Quest 2 開発メモ

最終更新日:2020年10月23日

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

更新履歴

(2020年10月23日)「PC の画面に別視点の映像を表示するには」に URP の方法について追記
(2020年10月20日)「Off-Store Distribution」に Facebook Connect の動画を追加、「アカウントを変更するには」「ファクトリーリセットするには」を追加
(2020年10月18日)「Unity Hub で Unity をインストールする」に画像を追加
(2020年10月17日)「視野全体の解像度の変更」を更新
(2020年10月15日)「Oculus Quest 2 かどうかを判定するには」を追加、「Oculus Browser」の項目を更新、「Oculus Integration をアップデートするには」を追加


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

Unity の Oculus Quest 対応の概要

Unity は Oculus Quest / Oculus Quest 2 に正式に対応しています。Oculus Quest は Android ベースですので、Android アプリとしてビルドします。

Unity の標準機能だけでも Oculus Quest で動く VR アプリはビルドできますが、Oculus Quest 固有の機能の多くを利用するには Asset Store にある Oculus Integration をインポートして使用する必要があります。基本的には Oculus Integration が必要ですので、以降本ページでは Oculus Integration ベースで解説します。

必要な Unity のバージョンは Set Up Development Environment のページで確認できます。2020年10月現在は 2018.4 以降に対応しており、筆者の手元では 2019.4 および 2020.1 で大丈夫そうです。

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

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

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

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

Quest アプリをビルドする手順を示します。

Unity Hub で Unity をインストールする

Unity Hub で Unity をインストールします。インストールするときに、モジュール追加のところで Android Build Support と Android Build Support のタブを開いたところにある Android SDK & NDK Tools、OpenJDK にすべてチェックを入れてください。

Unity でプロジェクトを作成する

Unity の新規プロジェクトを「3D」テンプレート(Legacy Render Pipeline)または「Universal Render Pipeline」テンプレートで作成し、以下の手順を行います。

  • Build Settings を開いてプラットフォームを Android に、Texture Compression(テクスチャの圧縮方式)を ASTC に変更して Switch Platform する
  • Player Settings で Player > Other Settings > Graphics APIs の Vulkan を削除する
  • 必要なら Color Space も Linear に変えておく
  • その下のほうの Minimum API Level を「Android 6.0 ‘Marshmallow’ (API level 23)」に変更する

Oculus Integarion をインポートする

Asset Store にある Oculus Integration をプロジェクトにインポートします。

インポートが完了すると Oculus の新しいプラグインを認識しましたというダイアログメッセージが出るので、「Yes」「Upgrade」「Restart」等をクリックしてください。

XR Plug-in Management を有効化する

以下の手順でUnity の XR サポートを有効にします。

  • Window > Package Manager を開いて、XR Plugin Management パッケージと Oculus XR Plugin パッケージ(1.4.0 以降)をインストールする
  • Edit > Project Settings > XR Plug-in Management で Android と Standalone の “Oculus” にチェックを入れる

ビルド・実行する

試しに Project ウィンドウの Oculus/VR/Scenes/ControllerModels シーンを開いてみてください。

Build Settings を開き Oculus Quest を接続して Build and Run ボタンを押し、適当な .apk ファイル名を指定するとビルドと実機への転送が始まります。初回ビルド時に多数のシェーダーのビルドが走りますが、2度目以降はキャッシュされます。成功するとアプリが起動し、コントローラーで操作ができます。

ビルドしても動かないときは

Quest の画面が真っ暗のまま動かないときは、Unity の XR サポートがきちんと有効になっていないケースが多いです。

  • Window > Package Manager で XR Plugin Management パッケージと Oculus XR Plugin パッケージがインストールされているか、バージョンが新しいかを確認してください。
  • Edit > Project Settings で XR Plug-in Management の Oculus と Initialize XR on Startup のチェックが入っているかを確認してください。

Quest へのインストール時にエラーが出るときは、アプリを一度アンインストールすると上手く行く場合があります。

Build and Run したアプリを再度実行するには

ビルドして実機に転送したアプリは、Quest に格納されていていつでも実行できます。「アプリ(Apps)」メニューの右上の「すべて」を「提供元不明(Unknown Sources)」に変更したところに入っています。

右端の「︙」ボタンからアンインストールもできます。

Unity のエディタで再生するには

Oculus Integration は PC ヘッドセットにも対応しています。Quest を Oculus Link で接続すると PC ヘッドセットとして認識され、Unity のエディタ上で再生できます。ビルドしなくても実行できるため開発が楽になります。

Rift S も使用できます。Rift S だとバッテリーや接続の不安定さを気にしないでいいメリットが、Quest だとハンドトラッキングも使用できるメリットがあります。「Oculus Link でハンドトラッキングを使用するには」を参照してください。

Quest のログ出力を見るには

Unity の Android Logcat パッケージをインストールしておくと便利です。

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

なお Quest から Android Logcat に大量のログが出力されている場合、Unity が非常に重くなることがあるので注意してください。

Oculus Integration をアップデートするには

Oculus Integration のバージョンを上げるときは以下の手順で行えばだいたい大丈夫です。

  • Unity をいったん終了する(プラグインの DLL を解放するために必須です)
  • Assets/Oculus フォルダを削除
  • Unity を起動しプロジェクトを開いて Oculus Integration を再インポート

こちらのページに公式の説明があります。

Oculus Developer Hub について

Oculus Developer Hub という開発用のポータルツールが提供されています。ヘッドセット内の映像の中継表示や、ガーディアンや近接センサーの無効化、アプリの起動やアンインストール、Oculus が提供するツールのダウンロード等の機能がありますので、インストールしておくと便利です。


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

グラフィックス設定

レンダリング・パイプラインはレガシーと Universal Render Pipeline のどちらでも大丈夫です。リニアカラーにも対応しています。フォワードレンダリングにするのが基本になります。

アンチエイリアスは Project Settings > Quality > Anti Aliasing で設定します。2x はとても軽量でかつ効果が大きいので最低でも必ずかけておいたほうがいいです。4x はポリゴンのエッジがさらにすっきりしますが若干重めです。重いシェーダーで画面の広範囲が覆われたときに負荷増が顕著になります。8x は 4x と違いが分からず、4x までしか効かない感じがします。

その他、

  • Project Settings > Oculus の Stereo Rendering Mode を Multiview にする(Standalone のほうは Single Pass Instanced にする)
  • Dynamic Batching と Static Batching をオンにする(Graphics Jobs は使わないこと)

が基本設定になると思います。

関連項目として「描画解像度について」も参照してください。

カメラの配置

Oculus Integration を使用する場合、シーンのカメラとしてデフォルトの Main Camera の代わりに Oculus/VR/Prefabs/OVRCameraRig プレハブをシーンに配置します。

Unity の XR 機能を有効にすると、Render Texture が設定されていない Camera の Transform がヘッドセットの動きによって上書きされるようになりますが、これによって OVRCameraRig の孫の CenterEyeAnchor オブジェクトがヘッドセットに追従します。

OVRCameraRig は、シーン内のプレイヤーの視点の位置(正確には両目の中間)に配置します。その上で、実行中にちょうどいい場所に立つ、椅子に深く座るなどしてコントローラーの Oculus ボタン長押しでリセンターすることで位置合わせができます。

また、立って体験するソフトを作る場合は、OVRCameraRig オブジェクトをシーンの地面と同じ高さに配置して、OVR Manager コンポーネントの Tracking Origin Type を Floor Level に変更します。

ビルド設定

Oculus Store にアプリを提出する場合は Project Settings で Scripting Backend を IL2CPP にして ARM64 でビルドする必要があります。が、IL2CPP はビルドが重すぎるので、開発中や、ストアにリリースするつもりのない制作物では Mono でいいかもしれません。

adb コマンドについて

adb (Android Debug Bridge) は Android デバイスの各種操作を行うためのコマンドラインツールです。Quest でも使用できます。

adb コマンドは下記ページからダウンロードできるほか、Unity のインストール時に同梱されるものを使用することもできます。Unity の Android Logcat パッケージをインストールして、Android Logcat のウィンドウの右上の Open Terminal をクリックすると Platform-Tools のインストールフォルダが開きます。

よく使うコマンドをいくつか紹介します。

Quest の接続を確認するには

$ adb devices

アプリをアンインストールするには

$ adb uninstall [パッケージ名]

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

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

$ adb shell cmd package list packages

apk ファイルをインストールするには

$ adb install [apk ファイル]

アプリを実行するには

下記コマンドで Unity でビルドした指定パッケージ名のアプリを実行できます。

$ adb shell am start -n [パッケージ名]/com.unity3d.player.UnityPlayerActivity

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

$ adb shell ifconfig

モーションコントローラーについて

Quest は Touch というモーションコントローラーを使用します。

Touch コントローラーは、主に外周リング部に埋め込まれた赤外線 LED を Quest 本体の赤外線カメラで位置トラッキングする仕組みになっています。バッテリーは左右それぞれ単三電池一本です。エネループ等も使用できます。連続使用で3時間から4時間ほど動作します(Quest 2 では稼働時間が伸びているようです)。

コントローラーの位置を取得するには

Oculus/VR/Prefabs フォルダにある OVRCameraRig をシーンにドロップし再生すると、OVRCameraRig の孫の LeftHandAnchor、RightHandAnchor が Touch の位置になります。

また、OVRInput.GetLocalControllerPosition / GetLocalControllerRotation で位置を取得することもできます。

コントローラーを VR 空間に表示するには

OVRCameraRig の LeftHandAnchor および RightHandAnchor に OVRControllerPrefab をアタッチして、右手の OVRControllerPrefab の Controller を R Touch に変更してください。

Oculus/VR/Scenes/ControllerModels シーンに上記セットアップ済みの OVRCameraRig があるので参考になります。

コントローラーの操作で動く手を表示するには

OVRCameraRig の LeftHandAnchor に CustomHandLeft を、RightHandAnchor に CustomHandRight をアタッチすると、コントローラーの操作で動く手を表示できます。

Oculus/SampleFrameworks/Usage/CustomHands シーンに上記セットアップ済みの OVRCameraRig があるので参考になります。

トリガーやボタンの状態を取得するには

OVRInput クラスで Touch のボタン・スティック・トリガーの状態を取得できます。

OVRInput は異なる種類のコントローラーの入力を抽象化して取得できるようになっていますが、ややこしいので、とにかく Touch の入力を一通り読む方法をコードの形で示します。正確なところは OVRInput のドキュメントページを参照してください。

ボタン・トリガーを押したか調べるには

if (OVRInput.GetDown(OVRInput.RawButton.A))
{
    Debug.Log("Aボタンを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.B))
{
    Debug.Log("Bボタンを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.X))
{
    Debug.Log("Xボタンを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.Y))
{
    Debug.Log("Yボタンを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.Start))
{
    Debug.Log("左手メニューボタンを押した(オン・オフ不安定なので注意)");
}

if (OVRInput.GetDown(OVRInput.RawButton.RIndexTrigger))
{
    Debug.Log("右人差し指トリガーを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.RHandTrigger))
{
    Debug.Log("右中指グリップを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.LIndexTrigger))
{
    Debug.Log("左人差し指トリガーを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.LHandTrigger))
{
    Debug.Log("左中指グリップを押した");
}

GetDown ではなく Get を使うと押しっぱなしの状態で true、GetUp でリリースの瞬間に true になります。

なお、右手の Oculus ボタンの状態は取得できません。

トリガーの入力をアナログ値で取得するには

// 右人差し指トリガー
float rTrigger1 = OVRInput.Get(OVRInput.RawAxis1D.RIndexTrigger);
// 右中指グリップ
float rTrigger2 = OVRInput.Get(OVRInput.RawAxis1D.RHandTrigger);
// 左人差し指トリガー
float lTrigger1 = OVRInput.Get(OVRInput.RawAxis1D.LIndexTrigger);
// 左中指グリップ
float lTrigger2 = OVRInput.Get(OVRInput.RawAxis1D.LHandTrigger);

離すと 0.0、押し込むと 1.0 になります。ただし、完全に押し込んでも 1.0 まで上がらなかったり、すぐに 1.0 にならなかったりしますので、押し込んだかどうか判定する場合には閾値を設ける必要があります。

選択、キャンセル入力を取得するには

Button.One、Two を使用すると便利です。それぞれ Touch の A/X ボタン、B/Y ボタンにマップされていますが、セットアップ時の説明にも表示されるスタンダードな操作となっています。

if (OVRInput.GetDown(OVRInput.Button.One))
{
    Debug.Log("選択した");
}
if (OVRInput.GetDown(OVRInput.Button.Two))
{
    Debug.Log("キャンセルした");
}

アナログスティックの入力を取得するには

下記で取得できます。Vector2 の X 軸が左 -1.0 ~右 1.0、Y 軸が下 -1.0 ~上 1.0 になっています。

// 左手のアナログスティックの向きを取得
Vector2 stickL = OVRInput.Get(OVRInput.RawAxis2D.LThumbstick);
// 右手のアナログスティックの向きを取得
Vector2 stickR = OVRInput.Get(OVRInput.RawAxis2D.RThumbstick);

アナログスティックをボタンとして押し込むこともできます。

if (OVRInput.GetDown(OVRInput.RawButton.LThumbstick))
{
    Debug.Log("左アナログスティックを押し込んだ");
}
if (OVRInput.GetDown(OVRInput.RawButton.RThumbstick))
{
    Debug.Log("右アナログスティックを押し込んだ");
}

また、デジタル4方向の入力も取得できます。メニュー選択等に便利です。

if (OVRInput.GetDown(OVRInput.RawButton.LThumbstickUp))
{
    Debug.Log("左アナログスティックを上に倒した");
}
if (OVRInput.GetDown(OVRInput.RawButton.LThumbstickDown))
{
    Debug.Log("左アナログスティックを下に倒した");
}
if (OVRInput.GetDown(OVRInput.RawButton.LThumbstickLeft))
{
    Debug.Log("左アナログスティックを左に倒した");
}
if (OVRInput.GetDown(OVRInput.RawButton.LThumbstickRight))
{
    Debug.Log("左アナログスティックを右に倒した");
}

if (OVRInput.GetDown(OVRInput.RawButton.RThumbstickUp))
{
    Debug.Log("右アナログスティックを上に倒した");
}
if (OVRInput.GetDown(OVRInput.RawButton.RThumbstickDown))
{
    Debug.Log("右アナログスティックを下に倒した");
}
if (OVRInput.GetDown(OVRInput.RawButton.RThumbstickLeft))
{
    Debug.Log("右アナログスティックを左に倒した");
}
if (OVRInput.GetDown(OVRInput.RawButton.RThumbstickRight))
{
    Debug.Log("右アナログスティックを右に倒した");
}

ボタン・スティック・トリガーに触れているか調べるには

中指グリップとメニューボタン、Oculus ボタン以外について、指が触れているかどうかを調べることができます。

if (OVRInput.Get(OVRInput.RawTouch.LIndexTrigger))
{
    Debug.Log("左人差し指用トリガーに触れている");
}
if (OVRInput.Get(OVRInput.RawTouch.LThumbstick))
{
    Debug.Log("左アナログスティックに触れている");
}

if (OVRInput.Get(OVRInput.RawTouch.RIndexTrigger))
{
    Debug.Log("右人差し指用トリガーに触れている");
}
if (OVRInput.Get(OVRInput.RawTouch.RThumbstick))
{
    Debug.Log("右アナログスティックに触れている");
}

if (OVRInput.Get(OVRInput.RawTouch.A))
{
    Debug.Log("Aボタンに触れている");
}
if (OVRInput.Get(OVRInput.RawTouch.B))
{
    Debug.Log("Bボタンに触れている");
}
if (OVRInput.Get(OVRInput.RawTouch.X))
{
    Debug.Log("Xボタンに触れている");
}
if (OVRInput.Get(OVRInput.RawTouch.Y))
{
    Debug.Log("Yボタンに触れている");
}

近接センサーの入力を調べるには

人差し指用トリガーとアナログスティックには近接センサーがあり、指が近づいた(ちょっと浮いている)状態を取得できるようになっています。

if (OVRInput.Get(OVRInput.RawNearTouch.LIndexTrigger))
{
    Debug.Log("左人差し指用トリガーの近くに指がある");
}
if (OVRInput.Get(OVRInput.RawNearTouch.LThumbButtons))
{
    Debug.Log("左アナログスティックの近くに指がある");
}

if (OVRInput.Get(OVRInput.RawNearTouch.RIndexTrigger))
{
    Debug.Log("右人差し指用トリガーの近くに指がある");
}
if (OVRInput.Get(OVRInput.RawNearTouch.RThumbButtons))
{
    Debug.Log("右アナログスティックの近くに指がある");
}

この近接センサーを使用して、指をさしている状態を取得できます。人差し指を伸ばすと RawNearTouch.RIndexTrigger が false になります。

コントローラーを振動させるには

OVRInput.SetControllerVibration を使用します。周波数と振動の大きさをそれぞれ 0~1 で指定します。両方とも0に設定すると振動が止まります。振動をオンにすると振動を続け、2秒後に止まるようになっています。多くの場合は自分で明示的に0にして止める必要があります。

周波数については変えても体感でほとんど分からないのですが、1よりも0のほうが心持ち荒い振動のような感じがします。

右手トリガーを引いている間振動を続けるサンプルスクリプトです。適当な GameObject にアタッチしてください。

using UnityEngine;

public class ControllerVibrationTest : MonoBehaviour
{
    void Update()
    {
        // 右手トリガーを引いたら振動を開始
        if (OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger, OVRInput.Controller.RTouch))
        {
            OVRInput.SetControllerVibration(0f, 1f, OVRInput.Controller.RTouch);
        }
        // 右手トリガーを離したら振動を停止
        if (OVRInput.GetUp(OVRInput.Button.PrimaryIndexTrigger, OVRInput.Controller.RTouch))
        {
            OVRInput.SetControllerVibration(0f, 0f, OVRInput.Controller.RTouch);
        }
    }
}

ハンドトラッキングについて

ハンドトラッキングを使用するには

まず Quest の「設定 > デバイス > ジェスチャーコントロールとコントローラー」の「ジェスチャーコントロール」をオンにしてハンドトラッキングを有効にしてください。

Oculus/VR/HandTest シーンがハンドトラッキングの最小限のサンプルシーンなので、こちらを動かしてみるのが手っ取り早いです。シーンを開いたら OVR Manager の Hand Tracking Support を Controllers And Hands に変更してビルドしてみてください。

OVRCameraRig の LeftHandAnchor / RightHandAnchor に OVRHandPrefab と OVRControllerPrefab がアタッチされていて、現在の入力に応じて手またはコントローラーが適宜表示されるようになっています。

Oculus Link を使用して、Unity のエディタ上でハンドトラッキングを使用できます。ビルドしなくても動作をテストできるため、ハンドトラッキングを使用したアプリの開発が楽になります。

「設定 > デバイス > ジェスチャーコントロールとコントローラー」の「手とコントローラーの自動切り替え」をオンにした状態で Oculus Link を有効にしてください。このオプションがオフだと、ハンドトラッキングをオンにしていても Oculus Link を接続した時点でオフに戻ってしまうのでエディタで手が使用できないようです。

手のマテリアルを変更するには

OVRHandPrefab を使用している場合、Skinnded Mesh Renderer に BasicHandMaterialがアサインされているので、これを変更することで手のマテリアル・テクスチャを変更できます。

指でつまむ動作を取得するには

左右の OVRHandPrefab にアタッチされている OVRHand に対して GetFingerIsPinching(finger) を呼ぶと、それぞれの指先がほかのいずれかの指先とくっついているかどうかを true / false で取得できます。

finger の値
親指 OVRHand.HandFinger.Thumb
人差し指 OVRHand.HandFinger.Index
中指 OVRHand.HandFinger.Middle
薬指 OVRHand.HandFinger.Ring
小指 OVRHand.HandFinger.Pinky

たとえば、親指と人差し指でつまむ形をしているかどうかは下記で判定できます。

public class FingerPinchTest : MonoBehaviour
{
    [SerializeField]
    OVRHand ovrHand;

    void Update()
    {
        if (ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Index) &&
            ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Thumb))
        {
            Debug.Log("つまんでる!");
        }
    }
}

親指と人差し指、親指と中指あたりでつまむ動作は比較的正しく取得できますが、3本以上になるとだいぶ怪しくなります。また、指先と指先がくっついているかの判定であって、指が立っているかどうかを判定するわけではないことに注意してください(たとえばグー・チョキ・パーの認識には使用できない)。

また、指先同士の接触の度合いを GetFingerPinchStrength で取得できます。指先と指先が離れていると0で、近づけると接触する数cmほど前から数値が上がっていき、接触する直前で1になります。

現在ハンドトラッキングかどうかを調べるには

OVRInput.IsControllerConnected を使用すると、現在 Touch コントローラーを使用しているか、ハンドトラッキングを使用しているかを調べることができます。

using UnityEngine;

public class ControllerChecker : MonoBehaviour
{
    void Update()
    {
        var usingHand = OVRInput.IsControllerConnected(OVRInput.Controller.Hands);
        var usingTouch = OVRInput.IsControllerConnected(OVRInput.Controller.Touch);

        Debug.Log($"usingHand = {usingHand} / usingTouch = {usingTouch}");
    }
}

なお、OVRInput.Controller.Hands と OVRInput.Controller.Touch は切り替わりの瞬間に両方とも false になっている場合があります。

キーボードで文字を入力するには

アプリ内で Quest のキーボードを呼び出して文字入力に使用できます。

Project ウィンドウの Oculus/OculusProjectConfig で Focus Aware と Require System Keyboard を有効にして、TouchScreenKeyboard.Open でキーボードが開きます(Quest 実機のみ)。TouchScreenKeyboard.text で入力文字を取得できます。

また、Unity UI(uGUI) で Input Field をアクティブにしてもシステムキーボードが表示されます。

Oculus ボタンを押したときの処理

アプリ実行中に右手コントローラーの Oculus ボタンを押すとシステム UI がオーバーレイ表示されますが、このときにアプリを一時停止する、コントローラーの表示を消す等適切な処理を行う必要があります(VRC.Quest.Input.4)。

あらかじめ Project ウィンドウの Oculus/OculusProjectConfig で Focus Aware にチェックを入れてください。Oculus ボタンを押すと OVRManager.InputFocusLost イベントが、復帰すると OVRManager.InputFocusAcquired イベントがトリガーされます。

ポーズ処理の基本としては、Time.timeScale をゼロにするのが簡単です。Oculus/SampleFramework に入っている PauseOnInputLoss.cs が参考になります。

ヘッドセットをはずした・スリープした等を検知するには

ヘッドセットをはずすと OVRManager.HMDUnmounted イベントがトリガーされます。また、Quest 本体のスリープと復帰で MonoBehaviour.OnApplicationPause が呼び出されます。

その他、Quest のアプリケーションライフサイクルで送られてくるイベントの一覧が下記ページにあります(InputFocusLost についてはまだ記載がないようです)。

Oculus Quest 2 かどうかを判定するには

OVRManager.systemHeadsetType で使用しているヘッドセットの種類が取得できます。SystemHeadsetType 列挙型で Oculus_Quest または Oculus_Quest_2 が返ってきます。

Oculus Link で接続している場合は Oculus_Link_Quest になります。

ビルドを速くするには

IL2CPP ビルドをできるだけ避ける

Oculus Store で リリースするためには IL2CPP/ARM64 でビルドする必要がありますが、開発中は Mono/ARMv7 でビルドするようにするととても楽です。

USB 3.0 ケーブルを使う

USB 3.0 ケーブルを使うとビルドした apk ファイルの Quest への転送時間が短くなります。下記エントリが参考になります。

Skip Unneeded Shaders

Unity のモバイルビルドではグラフィックス性能によって Tier 1 から Tier 3 までの描画設定が切り替わるようになっていますが(Project Settings > Graphics を参照)、Quest では Tier 2 しか使用されません。Tier 2 で使用されるシェーダーのみをビルドする設定を有効にするとビルド時間が短くなります。

Oculus > Tools > Oculus Platform Tool でウィンドウを開くと Project ウィンドウに Oculus/OculusProjectConfig が生成されますので、選択して Skip Unneeded Shaders をチェックしてください(Oculus Integration 17.0以降)。

シェーダーストリッピングの処理は OVRShaderBuildProcessor.cs で行われています。

OVR Scene Quick Preview

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

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

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

OVR Build APK and Run

Oculus > OVR Build > OVR Build APK and Run でビルドすると、ビルドの最終段の “Building Gradle project” がキャッシュされ、ビルド時間が数割短縮されます。ショートカットキーが割り当てられており、Ctrl+K で実行できます。

このメニューは Unity のプラットフォームを Android にしないと表示されないので注意してください。また、Android Logcatを使用している場合は、実行開始時にフィルターが自動で設定されないため自分で設定する必要があります。

パフォーマンス最適化

フレームレートの維持の必要性

Oculus Store でリリースする Quest アプリはガイドラインにより、黒画面になっているときやシーンの読み込み中を除き 72 fps で 45 分間連続動作することが求められます(VRC.Quest.Performance.1)。

72 fps 動作するためには、並列して動作する CPU と GPU の1フレームあたりの処理がどちらも 13.888… ミリ秒以内に収まっている必要があります。Quest は性能の高くないモバイル機ですので、最適化の方法についてよく知っておく必要があります。

Quest の CPU・GPU について

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

Quest は Snapdragon 835 を搭載しています。CPU は 8 コアで、4 つが性能重視の Performance コア(Cortex-A73)、4 つが省電力重視の Efficiency コア(Cortex-A53)です。アプリの実行に割り当てられているのは 3 つの Performance コアで、残りの 1 つの Performance コアはタイムワープとシステムサービスに、4 つの Efficiency コアはトラッキングやその他のシステムソフトウェアに使用されているとのことです。

GPU は Snapdragon 835 に統合されている Adreno 540 です。多くのモバイル GPU 同様タイルベースレンダリングであることに注意が必要です。

CPU・GPU レベルについて

Quest の CPU・GPU は、バッテリー消費を抑えつつフレームレートを維持するために、CPU・GPU レベルという形でクロック周波数が変動します。現在のレベル・クロック周波数は OVR Metrics Tool を使うとヘッドセット内で確認できます。

最低レベルを下記 API で設定できます。たとえば 2 に設定すると、通常時がレベル 2 で、負荷が増えて処理オーバーしそうになるとレベル 3、4 と上がっていき、処理に余裕ができるとゆっくりと 2 に戻っていきます。

OVRManager.cpuLevel = 2;
OVRManager.gpuLevel = 2;

できるだけ低いレベルでアプリが 72 fps 動作するようにしておくのが好ましいですが、低いレベルに設定していると突然負荷がかかったときにフレーム落ちする場合があります。このあと負荷がかかる処理が来ると分かっているようなときに、あらかじめレベルを上げておくことができます。

注意が必要なのがパフォーマンス評価のときで、レベルによって CPU・GPU の使用率の数値が変動します。使用率を比較する場合はレベルを 4(最大)に設定して固定しておいたほうがいいでしょう。

パフォーマンス最適化に使用できるツール

Quest のパフォーマンス最適化に使用できるツールは Oculus、Unity、Google、Qualcomm から提供されているものやオープンソースのツール等多岐に渡ります。どれを使えばいいか迷ってしまいますが、うち特に効果的なものをいくつか紹介します。

OVR Metrics Tool

真っ先に使用するべきツールがこれになります。フレームレートや Quest の各種メトリクスをヘッドセット内でオーバーレイ表示できます。アプリがどんなシチュエーションで重くなるかを簡易的に確認できます。

下記ページから apk ファイルをダウンロードして adb install でインストール、Quest で起動すると設定画面が出てきますので、「Enable Persistent Overlay」を有効にすると常時表示された状態になります(表示されなくなったときは電源ボタンで一度スリープして復帰してみてください)。

まずは設定画面の真ん中にあるプリセットの「BASIC」ボタンあたりをクリックしてください。また、デフォルトでは表示位置が上すぎると思いますので、Pitch を調整してみてください。

STATS タブで表示項目をひとつひとつオン・オフできます。多数の項目がありますが、特に表示しておきたい項目を下記に列挙します。

項目 表示 説明
Average FPS FPS 平均フレームレート
CPU Level CPU L 現在の CPU レベル(0-4)
GPU Level GPU L 現在の GPU レベル(0-4)
GPU Utilization GPU U GPU 使用率(0-100)
Stale Frame Count STALE フレーム落ちした数
Foveation Level FOV 現在の Foveated Rendering のレベル(0-4)

CPU 使用率について、STATS の下のほうにある「CPU Utilization (Core 0-7)」を有効にするとコアごとの数値を表示できます。Core 0-3 が Performance コア、4-7 が Efficiency コアのようです。

また、adb shell ovrgpuprofiler -e を実行すると GPU の細かい項目も有効にできるようになります。無効に戻すには -d オプションです。

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

Unity のプロファイラー

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

上の画像のように Timeline 表示にして、Quest の1フレームの CPU の実行処理の詳細を調べられます。画像のように CPU Usage の列が 13.888… ミリ秒で安定して短冊状になっているのが CPU または GPU の処理オーバーが起きていない正常な状態です。

RenderDoc

RenderDoc はオープンソースのフレームデバッガです。Quest 実機で描画コールの実行をトレースしたり、おおまかな実行時間を計測表示できます。Quest 用に機能が追加された RenderDoc for Oculus が Oculus から提供されていて(Windows 専用)、タイルベースレンダリングのタイムラインを表示したり、Quest の各種メトリクスを表示できるようになっています。

Oculus のブログに使い方が詳しいです。描画コールごとの実行時間が計測表示できますが、タイルベースレンダリングなので参考程度にとのことです。

Snapdragon Profiler

Qualcomm の公式ツールです(Qualcomm の開発者アカウント作成が必要)。Snapdragon の各種メトリクスを詳細表示できます。Snapdragon の CPU 各コアごとの使用率や、タイルベースレンダリングのタイル数等を確認できます。通常は上記の 3 つのツールで十分なので、使用する機会は少ないかもしれません。

その他の参考になる情報

コアな情報として、Oculus のブログの下記エントリに Quest のレンダリングパイプライン、タイムワープと Extra Latency Mode の動作の解説があります。

下記エントリに OpenGL と Vulkan でのタイルベースレンダリングの動作についての解説があります。

Qualcomm のサイトの「Adreno OpenGL ES Developer Guide」に Adreno のシェーダー等の最適化の Tips が載っています。

描画解像度について

VR ヘッドセットはディスプレイの解像度およびリフレッシュレートが高く、ピクセルの描画が GPU の大きな負荷になります。Standard Shader やユニティちゃんトゥーンシェーダー等、フラグメントシェーダーが重いマテリアルで視野の広範囲が覆われている場合、描画解像度を調整することで、見た目をあまり損なわずに GPU の計算量を下げられる場合があります。

視野全体の解像度の変更

下記 API で視野全体の描画解像度を変更できます。0.9 や 0.8 等に試しに下げてみるのがおすすめです。

using UnityEngine.XR;
...
XRSettings.eyeTextureResolutionScale = 0.5f;

現在の描画解像度は、OVR Metrics Tool の STATS で Eye Buffer Width と Eye Buffer Height の項目を表示すると確認できます。

URP を使用している場合は、Universal Render Pipeline Asset の Render Scale でも変更できます。

周辺視野の解像度の変更

Fixed Foveated Rendering

目立たない周辺視野の描画解像度を下げることによって GPU 負荷を下げる VR 特有の最適化機能です。ケースによりますが、GPU 使用率が 10 %から数十%下がります。

下記 API で使用できます。

// Off、Low、Medium、High、HighTop のいずれかを設定
OVRManager.fixedFoveatedRenderingLevel = OVRManager.FixedFoveatedRenderingLevel.High;

現在のレベルは、OVR Metrics Tool の STATS で Foveation Level の項目をオンにすると確認できます。なお、シーンを開始して1フレーム待たないと設定が反映されない場合がありました。

Foveated Rendering の仕組みとしては、タイルベースレンダリングのタイルごとに解像度を変えているようです。詳細の解説がこちらにあります。

Dynamic Fixed Foveated Rendering

描画負荷によって自動的に Foveated Rendering のレベルを変更させます。かなり使い勝手がいいので描画負荷が大きく変動するコンテンツでおすすめです。通常はオフの状態で、負荷が増えてフレーム落ちしそうになるとレベルが徐々に上がっていき、負荷が減るとまた徐々に下がっていきます。

OVRManager.useDynamicFixedFoveatedRendering = true;

で有効になり、OVRManager.fixedFoveatedRenderingLevel には最大レベルを設定します。

テクスチャを綺麗に表示するには

テクスチャの描画品質を上げたい場合、こちらのエントリが非常に詳しく必読です。

圧縮フォーマットを ASTC にする

Quest のテクスチャ圧縮フォーマットは基本的に ASTC にします。

Build Settings でデフォルトの Texture Compression を ASTC にして、個々のテクスチャで調整が必要な場合は Format で RGB(A) Compressed ASTC の 4x4 block から 12x12 block までを選択します。ブロックサイズを大きくすると圧縮率が上がります(Apply してインスペクター最下部のテクスチャ容量の数値が変わるのを確認してください)。

ミップマップを適切に設定する

VR ではテクスチャに近づいたり離れたりすることが非常に多いです。距離に応じて適切な解像度で描画されるように、テクスチャのインポート設定で Generate Mip Maps をオンにします。

また、距離によってミップマップのポッピング(急な切り替わり)が起きないようにするには Filter Mode を Trilinear に変更します(そこそこ負荷が増えるようです)。

さらに、解像度が高めのミップマップレベルが使用されるように Mip Bias を設定します(インスペクタを Debug モードにしないと出てきません。Oculus の上記エントリでは -0.7 に設定しています)。

異方性フィルタリングを有効にする

地面や壁など斜めの角度から見ることが多いテクスチャは、インポート設定で Aniso Level を上げると綺麗に表示されます。

リフレッシュレートについて

Oculus Quest のデフォルトのリフレッシュレートは 72Hz ですが、OVRManager.display.displayFrequency で 60Hz に変更できます。

現在のリフレッシュレートの数値は UnityEngine.XR.XRDevice.refreshRate で取得できます。ただし Awake や Start では0が返ってくる場合があり、1フレーム待つ必要があります。サンプルコードを示します。

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

public class RefreshRateTest : MonoBehaviour
{
    IEnumerator Start()
    {
        // 1フレーム待たないと取得できない場合がある。
        yield return null;
        Debug.Log("XRDevice.refreshRate = " + XRDevice.refreshRate);
    }
}

フェードイン・フェードアウトするには

OVRScreenFade を使う

OVRScreenFade を CenterEyeAnchor にアタッチするとシーン開始時にフェードインします。目の前に半透明ポリゴンを描いて覆う仕組みになっています。

フェードアウトするには FadeOut 関数を呼びます。逆にフェードインする関数がないのですが、FadeOut 関数を参考に以下を書き加えるといいでしょう。

    public void FadeIn()
    {
        StartCoroutine(Fade(1, 0));
    }

OVRManager.SetColorScaleAndOffset を使う

別の方法としては、OVRManager の関数でヘッドセット内の画面全体のピクセルの色にフィルターをかけられます。Quest で効くのは第1引数のカラースケールだけで、カラーオフセットは効かないようです。

OVRManager.SetColorScaleAndOffset(Vector4 colorScale, Vector4 colorOffset, bool applyToAllLayers)

DOTween と SetColorScaleAndOffset を使用してフェードイン・フェードアウトするサンプルクラスです。

using DG.Tweening;
using UnityEngine;

public class Fader : MonoBehaviour
{
    Color filterColor;

    void Update()
    {
        if (OVRInput.GetDown(OVRInput.RawButton.A))
        {
            FadeTo(Color.white, 1f);
        }
        if (OVRInput.GetDown(OVRInput.RawButton.B))
        {
            FadeTo(Color.black, 1f);
        }
    }

    public void FadeTo(Color color, float durationSec)
    {
        DOTween.To(() => filterColor, c => filterColor = c, color, durationSec)
            .SetEase(Ease.Linear)
            .OnUpdate(() => OVRManager.SetColorScaleAndOffset(filterColor, Color.clear, true));
    }
}

アプリをリリースするには

Quest のアプリ配布手段について

Oculus Store

Quest の公式アプリストアといえば Oculus Store ですが、2020年10月現在、Oculus Store で Quest アプリをリリースするには厳しい企画審査を通過する必要があります。残念ながら、一般の個人開発者等には Oculus Store でのアプリのリリースは事実上不可能のようです。

Off-Store Distribution

Oculus の Facebook Connect でのアナウンスによると、ストア外でアプリのページを URL で直接開いてダウンロードできる新しいリリースチャンネルを Early 2021 予定で準備中とのことです。こちらについては Oculus Store ほどの厳しい審査はなく、有料アプリも可能とのことです(Higher install limits と言っているあたり、インストール数制限があるのかが気になります)。

apk ファイルの直接配布

ユーザーの Quest を開発者モードにしてもらって adb install コマンドでインストールすることが考えられます(いわゆるサイドローディング)。

SideQuest

サイドローディングのアプリを配布する非公式のアプリポータルとして SideQuest があります。PC にポータルソフトウェアをインストールして、Quest に apk ファイルをインストールできます。

インディーゲーム販売サイト itch.io の決済システムを利用して有料 apk ファイルの配布も活発に行われています。

Oculus Browser (WebGL / WebXR)

ネイティブアプリではなく、Quest のウェブブラウザ(Oculus Browser)で動くウェブアプリとして開発することも考えられます。この場合、Unity ではなく JavaScript で Three.js や A-Frame 等の WebGL ライブラリを使用して開発します。

Oculus Browser は Chromium ベースのブラウザで、 WebXR サポートが積極的です。ハンドトラッキング等の新仕様にも対応しています(どちらかというと Quest のハンドトラッキングを使用するために WebXR の API の策定が進むという趣になっていて、ある意味 Quest が WebXR のリファレンス実装のひとつになっています)。

Unity で WebXR で動くアプリを開発したい場合は、Unity の WebGL ビルドを WebXR に対応させる Mozilla の Unity WebXR Exporter があります。ただ、試しに使ってみたところ、フレームレートが低かったり、起動に数十秒かかったり、Quest や他のブラウザででしばしば動かなくなったりとまだあまり安心して使える感じではなさそうでした(2020年4月時点)。未確認ですが、2020年10月時点でも Oculus Browser で動作しないかもしれません。下記スライドを参照してください。

Oculus Store 向けアプリ作成時の Tips

ガイドラインのチェック

Quest Virtual Reality Check (VRC) Guidelines というアプリのガイドラインがあります。ストアでリリースするのでなくても参考になる項目が並んでいますので要チェックです。

パッケージ名を適切につける

Quest アプリは Unity の Project Settings の Player > Package Name をもとに識別されます(つまり、Package Name を変えると別のアプリとして認識されます)。

Oculus のダッシュボードにアップロードする apk ファイルをビルドする際に適切なパッケージ名を設定しておきます。通例、ドメイン名を逆順にした「com.[会社名].[プロダクト名]」のような名前をつけます。

ダッシュボードに一度でも apk ファイルをアップロードすると、以後パッケージ名が変更できなくなるので要注意です。

パッケージ名を変更した apk ファイルをアップロードしようとすると、

This upload uses a new package name, "[新パッケージ名]", but the package name must not change between versions. Please upload a new build with the original package name, "[旧パッケージ名]".

というエラーが出て、ダッシュボードからアプリを作り直すしか方法がありません。

App ID の設定

apk ファイルをビルドする際に App ID を設定する必要があります。Oculus のダッシュボードでアプリを作成して Getting Started API のページを開き、取得した App ID を Oculus > Platform > Edit Settings の Application ID のところに設定します。

アプリへの署名

apk ファイルをビルドする際に署名が必要です。Project Settings の Player > Publishing Settings > Keystore Manager… で署名ファイル(*.keystore)を作成して署名します。アプリのアップデートの際は同じ署名ファイルで署名する必要があります。設定したパスワードを忘れないように注意してください。プロジェクトファイルには保存されません。

Entitlement Check

Oculus Store で配信する apk ファイルは Oculus Store 経由でダウンロードしたときにのみ動くようにする必要があります(VRC.Quest.Security.1)。

Oculus/Platform/Samples/EntitlementCheck に EntitlementCheck.cs というサンプルスクリプトが入っていますので、これを適当なゲームオブジェクトにアタッチして Exit App On Failure をオンにしてビルドします。上の項目の App ID の設定をしておく必要があります。

Bundle Version Code の設定

Oculus のダッシュボードは Project Settings の Player > Other Settings > Bundle Version Code の数値でアプリのバージョンを識別しています。新しいバージョンの apk ファイルをアップロードするたびに Bundle Version Code の数値を増やしてビルドする必要があります。

コマンドラインでアプリをアップロードするには

Oculus が提供するコマンドラインツールを使用して、ダッシュボードに apk ファイルをアップロードできます。CI に組み込んでおくと便利です。

ダッシュボードから取得した App ID と App Secret を使用して、

ovr-platform-util.exe upload-quest-build --app-id [App ID] --app_secret [App Secret] --apk Build.apk --channel alpha

のようにしてアップロードします。

Quest 本体の Tips

apk ファイルをインストールするには

Quest を開発者モードにした上で、adb コマンドで adb install するか、Oculus Developer Hub をインストールしてあれば apk ファイルを My Device タブの UNKNOWN SOURCE にドラッグするとインストールできます。

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

開発時にはガーディアンの表示を切っておくと便利です。イベント展示や、アリーナスケールのコンテンツの開発の際にもオフにします。

Quest の「設定 > 開発者 > ガーディアン」(Settings > Developer > Guardian)でオン・オフの設定ができます。オフにするときに安全のため警告メッセージが表示されます。また、Oculus Developer Hub をインストールすると My Device タブの Gurdian でオン・オフの設定が可能です。

一度スリープすると設定が元に戻ってしまうので、スマートフォンの Oculus アプリで「その他の設定 > 電源の設定 > オートスリープ」でスリープ時間を最長の15分にしておくといいでしょう。

Quest のストレージにアクセスするには

Quest を PC に接続すると USB ストレージとして認識されます。

もし認識されない場合は、スマートフォンの Oculus アプリの「その他の設定>開発者モード」をオフ・オンしていると Quest の画面に「データへのアクセスを許可」ダイヤログが出てきて見えるようになる場合があります。

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

Oculus Developer Hub をインストール・起動して、My Device タブで Cast Device を実行するとヘッドセットの中の映像を中継できます(正方形表示)。ウィンドウサイズを変更すると大きく表示できます。なお、キャスト中はヘッドセットの近接センサーが無効になります。

scrcpy というツールもありますが、左右2画面の樽型表示になりますので、デモ用途等には正方形表示ができる Oculus Developer Hub のほうがおすすめです。

スクリーンショットを撮るには

Oculus ボタンを押してダッシュボードを開き、「写真を撮る」ボタンを押すと数秒後に撮影音が鳴ってスクリーンショットが保存されます(正方形)。撮影した画像は Quest を PC に接続して /Oculus/ScreenShots フォルダから読み出せます。

右手コントローラーの Oculus ボタンを押しながらトリガーを引くことでもスクリーンショットが撮影できます(できないこともあるっぽい?)。

Unity の Android Logcat パッケージの Capture Screen のボタンを押すとスクリーンショットが撮影保存できます(左右2画面の樽型)。

Oculus Developer Hub の My Device タブの Screenshot のボタンでスクリーンショットを撮影できます(左右2画面の樽型)。下の Media Directory のボタンで保存先のフォルダが開きます。

動画をキャプチャするには

Oculus ボタンを押してダッシュボードを開き、「録画」ボタンを押すと動画の録画が開始します(正方形)。キャプチャした動画は Quest を PC に接続して /Oculus/VideoShots フォルダから読み出せます。

Oculus Developer Hub の My Device タブの Record Video のボタンで動画を撮影できます(左右2画面の樽型)。下の Media Directory のボタンで保存先のフォルダが開きます。

アカウントを変更するには

Oculus アプリとのペアリングを解除するにはファクトリーリセットが必要です。次の項目を参照してください。

ファクトリーリセットするには

スマートフォンの Oculus アプリの「その他の設定」から「出荷時設定にリセット」を選択します。

Quest 本体のみで工場出荷時の状態に戻すには、電源オフの状態から、音量マイナスボタンを押しながら電源ボタン長押しで電源を入れます。Oculus ロゴが表示されたら電源ボタンだけを離してください。メニューが表示されるので、Factory reset を選択して実行します。

Quest と PC を Wi-Fi 経由で接続するには

Oculus Developer Hub の My Device タブで ADB over Wi-Fi をオンにして USB ケーブルを抜きます。

Quest は屋外で使用できるの?

おそらくコントローラーの赤外線 LED が太陽光にかき消されるため、強い晴天下では Quest コントローラーは 6DoF トラッキングができなくなりました。なお、Windows Mixed Reality ヘッドセットは同条件で正常に動作しました。

Oculus Link(Windows アプリ)編

Quest 単体向けのときと同様 Oculus Integration を使用します。Platform を「PC, Mac & Linux Standalone」にして、Project Settings > XR Plug-in Management で Standalone タブの Oculus のチェックが入っていることを確認してください。ビルドすると Oculus Link 用の .exe ファイルが作成されます。

あらかじめ Oculus ソフトウェアの設定を変更する必要があります。Oculus ソフトウェアのを起動して左の Settings を選択、General タブを選択して Unknown Sources をオンにします。この設定は一度変更すると Oculus のアカウントに保存されます。

PC の画面に別視点の映像を表示するには

Camera をシーンに追加し、Target Eye を「None (Main Display)」に設定してください。また、どちらかのカメラから余分な Audio Listener を削除してください。実行すると別視点の画面が PC 側に表示されます。

PC 側のカメラの Depth (priority) の数値をヘッドセット側のカメラより大きくしておく必要があります。もしくは、XRSettings.showDeviceView でヘッドセット側のカメラのミラー表示を無効にしてください(こちらのほうがより軽量なのではと思います)。

なお当然ですが、一画面余分にレンダリングしますので、そのぶん負荷が増えます。フレーム落ちする場合は、ディスプレイの解像度を下げてみてください。

困ったとき

Quest で起動すると画面が真っ暗のまま動かない

Android Logcat で「Unable to find OculusXRPlugin」という赤文字のエラーが出ている場合、Unity の Oculus XR Plugin パッケージを更新すると動くようになる場合があります。

Build and Run でビルド後に Quest で起動しない

Unity のコンソールに

DeploymentOperationFailedException: No activity in the manifest with action MAIN and category LAUNCHER. Try launching the application manually on the device.

というエラーがもし出ている場合は、Oculus > Tools > Remove AndroidManifest.xml で AndroidManifest.xml を削除してみてください。

その他の Tips

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

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

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

コントローラーのトリガーを引くと位置トラッキングをリセットするサンプルスクリプトです。

using UnityEngine;

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

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

PlayerPrefs はどこに保存されているの?

通常の Android だと /data/data/[パッケージ名]/shared_prefs/[パッケージ名].xml にあるはずなんですが、Quest ではアクセスできず、また、アクセスできる場所にそれらしいファイルは見つかりませんでした……。アプリをアンインストールすると初期化できます。


参考リンク

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