プログマのプログラマ日記

技術メモや自社サービスに関する記事を書いていく予定です。

Unity + Oculus Integrationで仮想手首ボタンの実装

Unity + Oculus Integrationを使ってHoloLens2の仮想手首ボタン(手首内側をくるっとカメラ方向に向けると現れるボタン)を実装してみました。

手首をくるっと回すと表示されるUI

githubにプロジェクトを共有しています(Assets/Sandbox/WristUI):
github.com

実装方針

最初はTrackingSpaceのLeft(Right)HandAnchorの子階層にUIをぶら下げて、カメラ方向を向いた時だけactiveにすれば簡単に実装できるだろうと考えていました。

最初に考えていた構成:

InteractionRigOVR
 +- OVRCameraRig
        +- TrackingSpace
              +- Left(Right)HandAnchor
                     +-  (ここにUIを追加する)

しかし、ハンドトラッキングとコントローラの両方に対応する場合、ハンドトラッキング使用時とコントローラ使用時で表示位置や回転が変わってしまう問題があり、別な方針で実装することにしました。(下図参照)
ハンドトラッキング/コントローラのどちらかしか使わないというケースであれば上記方針で充分かもしれません。

ハンドトラッキング使用時に以下のように表示されるように位置調整をしても...

コントローラ使用時には以下の位置に表示されてしまう。

最終的には

  • コントローラ使用時
    ControllerHands配下のLeft(Right)HandSynthetic/Left(Right)HandVisual/Oculus_Hand_L(R)の子要素にUIをぶら下げる
  • ハンドトラッキング使用時
    Hands配下のLeft(Right)HandSynthetic/Left(Right)HandVisual/Oculus_Hand_L(R)の子要素にUIをぶら下げる

という構成を取りました。

今回採用した構成:

InteractionRigOVR
 +- InputOVR
        +- ControllerHands
         |     +- Left(Right)HandSynthetic
         |           +- Left(Right)HandVisual
         |                  +- OculusHand_L(R)
         |                          +-  (コントローラ使用時は、ここにUIを追加)
         +- Hands
               +- Left(Right)HandSynthetic
                     +- Left(Right)HandVisual
                            +- OculusHand_L(R)
                                    +-  (ハンドトラッキング使用時は、ここにUIを追加)

実装コード

プロジェクトの全体はgithubに共有しています。

Assets/Sandbox/WristUI/Scenes/WristUICanvas

のシーンを参照してください。

使い方

環境構築などの前準備

本記事ではOculus Integrationの基本的なセットアップやHandPokeの基本的な設定方法は省略しています。

Oculus Integrationの環境構築とプロジェクト作成の手順については、こちらの記事を参照してください。

rhikos-prgm.hatenablog.com

また、HandPokeの最低限のセットアップ手順については、こちらの記事を参照してください。

rhikos-prgm.hatenablog.com

WristUIの配置と設定

1. シーン上の任意の場所にAssets/Sandbox/WristUI/Prefabs/WristUIのprefabを配置します。
1. GameObjectメニューまたはHierarchy上の右クリックメニューで「WristUI」を選択します。 (2022/11/23: Prefab配置だと他のプロジェクトに持っていったときにGhostHandにnullが設定される不具合があったため、GameObjectメニューからWristUIを生成するようにコードを修正しました。)

シーンビュー上では、prefabを配置した場所に半透明の手が表示されます。(以下GhostHandと呼びます)
GhostHandはEditモードでUIの位置調整するときに分かりやすくするためのもので、実行時には非表示になります。
2. WristUIのOvrCameraRigRefにInteractionRigOVR/InputOVRを設定します。
3. UIを左手首上に配置したい場合はIsLeftHandにチェックを入れます。右手首の場合はチェックを外します。
チェック状態に応じてGhostHandが左手・右手に切り替わります。 4. HandVisualsにInteractionRigOVR/InputOVR/ControllerHands/Left(Right)HandSynthetic/Left(Right)HandVisualを追加します。
コントローラを使わない場合は追加しなくてよいです。 5. HandVisualsにInteractionRigOVR/InputOVR/Hands/Left(Right)HandSynthetic/Left(Right)HandVisualを追加します。
ハンドトラッキングを使わない場合は追加しなくてよいです。

UIの配置と位置合わせ

  1. WristUI/anchor配下に表示させたいUIを配置します。
    何でもよいのですが、本説明では無地のボタン(Assets/Oculus/Interaction/Runtime/Prefabs/Poke/PokeInteractable)を配置することにします。
  2. UIが望む場所に表示されるようにanchorの位置を調整します。

以上で設定は完了です。実行結果は以下のようになります。