この記事はOculus Rift Advent Calendar 2018の4日目です。
Contents
はじめに
先日11月15日、Oculus SDKの一部であり、Oculus公式のUnity統合であるOculus Integration (Oculus Utilities for Unity)の最新版1.31が公開されました。このバージョンの大きな新機能が、Oculus Integrationを使ったままHTC Viveの動作がサポートされる、クロスプラットフォーム開発機能です。
以前からSteamVR SDKはViveにネイティブ対応しているのに加えRiftをサポートしていましたが、今回の対応により、Oculus側のSDKを使用した場合も、両方のヘッドセットに向けた開発が(少なくともUnityにおいては)可能になります。
前述の通りSteamVR SDKはViveとRift両方に対応していますが、問題なのが、SteamVR SDKを使用した場合はそのままではOculus Storeへの提出ができないという点です(その逆、つまり今回のOculus SDKのクロスプラットフォーム機能を使って実装したアプリをSteamに出すのは問題ないはず)。また、注目度の高いOculus Goや今後登場するOculus QuestはOculus SDKでしか動作しないため、これらにも対応したい場合いずれにしてもOculus SDKを避けて通ることはできません。もちろん、移植は色々な要素が絡むため、こういった機能があってもボタン一発とまではいきません。しかし、なるべく同じ機能の再実装を避けながら、PC・スタンドアローンを含む多くのプラットフォームに対応するという点においては、本機能は便利に使えるのではないでしょうか。
以下はOculusデベロッパードキュメンテーションのクロスプラットフォーム開発についてのページの私家版翻訳となります。2019/6/19追記: Integration 1.38に合わせて更新
Unityでのクロスプラットフォーム開発について
開発者が複数のプラットフォームやデバイスをターゲットしたい場合、Oculus Integration (Oculus Utilities for Unity)を使ってOpenVR向けのビルドを作成する事ができます。本記事では、クロスプラットフォーム開発で使用できるAPIについて、また通常のOculus向け開発と異なる点について解説します。APIの通常の使用方法や開発プロセスについてはドキュメンテーションの別ページで解説されていますので、本記事ではカバーしません。
開発者はクロスプラットフォーム開発機能を使うことで、OculusまたはSteamVRプラットフォームに向けて、追加工数を最低限に抑えながらそのまま動作するアプリを開発することができます。クロスプラットフォーム機能は、入力周りでは、6自由度のヘッドマウントディスプレイとコントローラー、即ちOculus Rift SとTouch、HTC Viveとそのコントローラー、Windows Mixed Realityヘッドセットとそのコントローラーなどに対応しています。
カメラ – OVRCameraRig
基本的にはOculus Utilities for Unityガイドに書かれた手順通りに進めます。既存のアプリをアップデートする場合、OpenVR HMDおよびそのコントローラーをトラッキングするには、既にあるカメラを削除し、改めてOVRCameraRigのPrefabをシーンにドラッグして入れる必要があります。
OVRCameraRig Prefabをシーンに入れる際、Tracking Originは必ずFloorLevelに設定してください。クロスプラットフォーム開発時は、EyeLevelはサポートされていません。
クロスプラットフォーム開発時は、コントローラーの動きに追随するオブジェクトはLControllerAnchorまたはRControllerAnchorの子になっている必要があります。
HMDトラッキング – OVRDisplay
以下のAPIで、トラッキング空間内でのHMDの加速度を取得することができます。これらのAPIはクロスプラットフォーム開発に対応しています。
OVRDisplay.velocity()
OVRDisplay.angularvelocity()
入力 – OVRInput
Oculusコントローラー使用時の使用方法はOVRInputのガイドページをご覧ください。クロスプラットフォーム開発時には、以下のAPIを使うことができます。
個別のボタン
以下のボタンは、Get()
, GetUp()
, GetDown()
に対応しています。Get()
はボタンの入力状態(押されていればtrue)、GetUp()
はそのフレームにボタンが離されたかどうか(離されていればtrue)、GetDown()
はそのフレームにボタンが押されたかどうか(押されていればtrue)を調べます。OculusコントローラーのマッピングについてはOVRInputページをご覧ください。
Button.PrimaryIndexTrigger
Button.SecondaryIndexTrigger
Button.PrimaryHandTrigger
Button.SecondaryHandTrigger
Button.PrimaryThumbstick
Button.SecondaryThumbstick
Button.Two
Button.Four
Axis1D.PrimaryIndexTrigger
Axis1D.PrimaryHandTrigger
Axis1D.SecondaryIndexTrigger
Axis1D.SecondaryHandTrigger
Axis2D.PrimaryThumbstick
Axis2D.SecondaryThumbstick
既存アプリとの下位互換性維持のため、これらのAPIのなかではOculus TouchとViveコントローラーの両方が“Touch”として扱われます。左のXRコントローラーはLTouch、右はRTouchとなります。
ボタンや各種入力の状態は、以下のいずれかに対して求めることができます。
Controller.LTouch
Controller.RTouch
Controller.Touch
[訳注: 上記API群は、原則的に(取得したいボタン名, [問い合わせたいコントローラー名])
という引数の構造を持っています。OVRInputで指定できるボタン名には“Primary” “Secondary”という指定があり、第二引数を省略して左手か右手どちらに対する問い合わせなのかを明示的に指定せずにPrimaryボタンの状態を取得した場合、「左手コントローラーが有効であれば左手側についている方、無ければ右手側の方」に問い合わせる挙動となります。細かい対応関係一覧はOVRInput内のButton enumを確認してください。次の段落はこれを踏まえています]
クロスプラットフォーム開発でOVRInputを使う場合、第二引数で問い合わせ先のコントローラーを明示的に指定したうえで、第一引数でPrimaryのボタンを指定する事をお勧めします。第二引数のコントローラーの左右の指定は必須ではありませんが、多くの場合指定しておいた方が簡単になります。以下にいくつか例を示します。
OVRInput.Get(Button.PrimaryHandTrigger, Controller.LTouch)
– 左手のXRコントローラーの「グリップ」トリガーまたはボタンが握り締められている間trueを返します。OVRInput.GetDown(Button.Two, Controller.LTouch)
– 左手のXRコントローラーの「上の方のボタン」が現フレームで押し込まれた場合trueを返します。これはOculus Touchの場合はYボタン、Viveコントローラーの場合は横棒が3つ入ったメニューボタンとなります。もし指定されていたのがRTouchだった場合は、TouchのBボタンになります。OVRInput.Get(Axis1D.PrimaryIndexTrigger, Controller.RTouch)
– 右手のXRコントローラーの人差し指トリガーが押し込まれている度合いを0.0-1.0の間で返します。
コントローラーの姿勢と加速度
以下のAPIでトラッキング空間内でのコントローラーの姿勢および加速度を取得することができます。これらのAPIはクロスプラットフォーム開発に対応しています。
GetLocalControllerPosition()
GetLocalControllerRotation()
GetLocalControllerVelocity()
GetLocalControllerAngularVelocity()
対応OpenVRコントローラーのボタンマッピング
HTC Viveコントローラー
上記で紹介したOVRInputの各種APIにおいて、HTC Viveコントローラーは、以下のボタン名に対応する形で扱われます。
Button.Two
– メニューボタンAxis2D.PrimaryThumbstick
– 静電容量式トラックパッドButton.PrimaryThumbstick
– トラックパッドの押し込みAxis1D.PrimaryIndexTrigger
– トリガーAxis1D.PrimaryHandTrigger
– コントローラー側面のグリップボタン
Microsoft Mixed Realityモーションコントローラー
上記で紹介したOVRInputの各種APIにおいて、Microsoft Mixed Realityモーションコントローラーは、以下のボタン名に対応する形で扱われます。(Microsoftのモーションコントローラーのページ、”Hardware Details”の項の画像を参照してください。)
Button.Two
– メニューボタンAxis2D.PrimaryThumbstick
– アナログスティックButton.PrimaryThumbstick
– タッチパッドの押し込みAxis1D.PrimaryIndexTrigger
– トリガーAxis1D.PrimaryHandTrigger
– グラブボタン
ハプティクス(振動) – SetControllerVibration()
クロスプラットフォームでのコントローラーを振動させる場合は、SetControllerVibration
APIを使用してください。OVRHapticsおよびOVRHapticsClip APIはクロスプラットフォーム開発に対応していません。
本APIの使用方法については、OVRInputガイドをご覧ください。クロスプラットフォーム開発デバイスの場合は、第一引数の周波数は1.0で固定、第二引数の振幅は0.0-1.0の範囲で指定する事が可能です。以下に例を示します。
OVRInput.SetControllerVibration(1.0f, 0.5f, Controller.RTouch)
– ピーク振幅の半分で、右のXRコントローラーを振動させます。この振動は、新たに振動が指定されるか、0を指定されて停止するかするまで続きます。また、新たに振動を指定せずに2秒経過した場合はタイムアウトで自動的に停止します。OVRInput.SetControllerVibration(1.0f, 0.0f, Controller.RTouch)
– 右のXRコントローラーの振動を停止します。
境界線・プレイエリア – OVRBoundary
OVRBoundaryを使用する事で、ユーザーのプレイエリア情報を取得・設定する事ができます。詳しくはOVRBoundaryガイドをご覧ください。以下のAPIがクロスプラットフォーム開発に対応しています。
GetDimensions()
GetGeometry()
SetVisible()
GetVisible()
GetConfigured()
オーバーレイ OVROverlay
OVROverlayを使ったオーバーレイの追加について詳しくは、VR Compositor Layersガイドを参照ください。クロスプラットフォーム開発においては、現時点ではワールド側に固定されたQuadオーバーレイのみがサポートされています。
クロスプラットフォームのオーバーレイを追加するには、シーンにQuadのGameObjectを追加し、MeshRendererとColliderコンポーネントを削除します。そのうえでQuadにOVROverlayコンポーネントを追加し、表示したいテクスチャを指定してください。
クロスプラットフォームアバター
Unityにおいて、Oculusアバターはクロスプラットフォーム開発に対応しています。クロスプラットフォームでのアバター使用について詳しくは、Unityクロスプラットフォームアバターサンプルシーンの解説ページをご覧ください。