Oculus Interation SDKを使って、ノーコードで簡単にオリジナルのハンドジェスチャを実装する

Quest Pro向けアプリケーションの開発でハンドジェスチャ認識機能に触れる機会があり、思っていた以上に楽かつ柔軟に、ノーコードでカスタムできることに驚きました。
SDK自体は1年以上前にでているので新しい内容ではないかもしれませんが、後学のために実装方法を残します!
筆者紹介:おたりな と申します!ゲーム・XRの開発に興味があり、MESON, inc.にてエンジニアとしてインターンをさせていただいております。
Quest Proのハンドジェスチャ
使用したものはOculus Interaction SDKで、Ray・Poke・Grab等のインタラクションを利用することができます。
公式ドキュメントはこちらです。
今回はその中でもハンドジェスチャ認識の機能に着目してお話しします。
サンプルシーン

動画のサンプルシーンは、Oculus Interationを導入後、Oculus/Interaction/Samples/Scenes/Examples/PoseExamples.unityから体験できます。
このサンプルを参考に、自身でハンドジェスチャを実装する流れを説明します。
開発環境
Unity 2022.3.0
Oculus Utilities 1.86.1
Oculus Integration 54.0
前準備
Oculus Integrationの導入
こちらのリンクからUnity Asset Storeにアクセスし、Oculus Integrationをインポートしてください。
一度でも追加したことがある場合、Windows → Package Managerを開き、My Assetsからインポートが可能です。
必須ファイルであるOculus/InteractionとOculus/VRが含まれているか確認してください。
Oculus Integration SDKを使用するための設定
Scene上に必要なObjectとその構造は画像の通りです。

以下の記事に記載されている「OVRCameraRigを組み立てる」の1~8を参考にしました。
9以降の手順で行われている参照渡しは、私が開発を行ったバージョンでは必要がなくなっていました。
また、本記事ではGrabやPokeには着目していないため、HandSyntheticを使用していない点に注意してください。
以上でOculus Interaction SDKを利用するための設定が終わりました。
ハンドジェスチャ判定の実装
今回は右手で銃の形のハンドジェスチャを認識させます。
オリジナルのハンドジェスチャを実装するために、まずSDKでどのようにハンドジェスチャの判定が行われているかを説明します。
以上のことを踏まえて、ハンドジェスチャーを実装します。
オリジナルハンドジェスチャ判定の実装
まず、Hierarchy上のプレハブ OVRHands/LeftHand/HandFeaturesLeft (HandFeaturesRight)に、Transform Feature State ProviderとFinger Feature State Providerコンポーネントが付いているかを確認します。もしなければ追加してください。
そしてFinger Feature State Providerコンポーネント内のFinger State Thresholdsに5つ、各指用の要素を追加します。詳しくは画像をご参照ください。

このFinger Feature State Thresholdsは、Curl・Flexion・Abduction・Oppositionの判定しきい値を指定するものです。デフォルトで提供されているもので問題ないとは思いますが、必要があれば調整も可能です。
Sceneに"GestureRecognizer"という名前のオブジェクトを作成し(名前は自由)、画像の通り複数コンポーネントを追加します。

各コンポーネントに設定している参照は以下の通りです。
-
HandRef× 2:それぞれ、OVRHands下のLeftHand,RightHandを参照させる。- 複数のジェスチャー認識を実装する場合:
親としてEmptyを作成しHandRef× 2を持たせ、ジェスチャ分の子オブジェクトを作成。それぞれの子オブジェクトにHandRefを1つ持たせ、親オブジェクトを参照させる。以降のコンポーネントは子ごとに追加する。
- 複数のジェスチャー認識を実装する場合:
-
Selector Unity Event Wrapper:発行したいイベントの登録、自オブジェクトのSelectorを参照させる。 -
Active State Selector:自オブジェクトのActive State Groupを参照させる。 -
Active State Group:Active StatesにElementを2つ分作り、自分オブジェクトのShape Recognizer Active StateとTransform Recognizer Active Stateを参照させる。 -
Shape Recognizer Active State:OVRHands下の、認識してほしい方(Left/Right)のHand下のHandFeaturesを参照させる。先述したShape Recognizerを コンポーネント内のShapesで参照することで、認識したいジェスチャを指定できる。Shape Recognizerの指定カスタムジェスチャを認識するための
Shape Recognizerを作成します。
フォルダ内で右クリック→Create/Oculus/Interaction/SDK/PoseDetection/Shapeを選択すると新規作成ができます。
今回は銃のような形を認識させたかったため、画像のようにShape Recognizerを作成しました。

作成したShape Recognizer
このShape Recognizerを、Shape Recognizer Active StateのShapesに追加します。

GestureRecognizerのShape Recognizer Active Stateに、作成したShape Recognizerを追加
-
Transform Recognizer Active State:Shape Recognizer Active State同様に参照させる。先述したTransform Feature Configsを利用して 手の向きをプルダウンから指定できる。Feature Thresoldsには大抵の場合Default Transform Feature State Thresoldsを参照、必要な場合はカスタムしたものを参照させる。Transform Feature Configsの指定手の向きを指定する場合はこちらでプルダウンから選択します。
今回は銃っぽさを想定して、画像のようにWrist Up: Trueを指定しました。

Transform Feature Configsで手の向きを指定
ジェスチャ認識時のイベント発行
イベント発行はSelector Unity Event Wrapperにて定義します。
検知された時のイベントはWhen Selected()、検知が外れた時のイベントはWhen Unselected()に登録します。
今回は検知した時に"Bang!"という文字列が表示され、検知が外れた際に文字列が消えるようにしました。

結果は動画のようになりました。

銃の形が検知されている様子(Wrist Up指定なし)

上のものにWrist Up: Trueの指定を加えたもの
補足
ここまで長々と書いたのですが...実は1から自力でつくる必要はなかったりします。
一番簡単な方法は、Oculus Integration SDKのサンプルに含まれているPoseExamplesシーンからコピペする方法です!
その次に簡単なのは、OVRCameraRig等々の設定を自分で行ったのち、Basic Pose Detection Posesプレハブを利用することです。
ただ、これらはサンプルとして実装されているエフェクト・音・複数のジェスチャー認識が含まれているため、余分なものは自身で判断して省く必要があります。
以上のような方法で、ノーコードでも柔軟にハンドジェスチャ認識の実装を行うことができます。
もちろん、コードで実装することも可能です🙆♀️
詰まったところ ~Hierarchy上の順番に注意!~
通常のハンドトラッキングは、OVRCameraRig/TrackingSpace/LeftHandAnchor, RightHandAnchorの下にOVRHandPrefabを配置するだけで実装できます。しかし今回はInteraction SDKを利用するため、OVRHandPrefabに加えて OVRInteraction + OVRHands が必要となります。
OVRHandsを利用する際はこちらが見た目の生成をしてくれるため、OVRHandPrefabの見た目生成に関わるコンポーネントは削除することを推奨します。(🚨InteractionSDKに含まれる、GrabやPokeを利用する際はまた別のオブジェクトを利用する必要があります)削除が必須ではないのですが、一番安全です。というのも、私は削除せずにいた結果うまく動かずにしばらくハマってしまったので...
その時のHierarchyは画像のような構造になっていました。

メニューボタンが表示されているので右手は検知されているはずが、モデルが表示されていない

正しく動作しなかった際のHierarchy構造
メッシュ生成を行わないOVRHandPreabと、行うOVRHandPrefab(ここでは明確化のため(Mesh)とつけています)の両方を配置していたのですが、右手のみがうまく認識されない問題に陥りました。
結論から言うとRightHandAnchorの中の構造でOVRHandPrefab(Mesh)がOVRHandPrefabよりも上に配置されていたことが原因でした。
OVRHandPrefab(Mesh)は無効化していたのですが、おそらくHierarchy上でより上位にある"OVRHandPrefab"が有効化されてしまったものだと考えられます。

修正後のHierarchy構造(どちらでも可)
これまでHierarchyの順番にはあまり意識を向けていなかったのですが、SDKなどを導入して裏側の処理が把握できない場合には注意する必要があることを学びました。
最後に
Quest Proにおけるハンドジェスチャー実装の話でした。ノーコードで簡単にカスタム可能であることが伝わり、実装の参考になれば幸いです!今回紹介したジェスチャ周りのこと以外にも、Oculus Integration SDKを利用することでコントローラーを使用しない自然な体験の実装が可能となっているので、ぜひ参照記事やSDKの中身をご覧ください。
今回はQuest Proに特化した話でしたが、今後Vision Proでのハンドジェスチャを含めたハンドトラッキングの実装にも引き続き注目していきたいと思います!
エンジニア絶賛募集中!
MESONではUnityエンジニアを絶賛募集中です! XRのプロジェクトに関わってみたい! 開発したい! という方はぜひご応募ください!
MESONのメンバーページからご応募いただくか、TwitterのDMなどでご連絡ください。
書いた人

大田 莉奈(あだな:おたりな)
ゲームエンジニア志望の慶應義塾大学理工学部4年生。
ゲーム・XR開発に興味があり、MESONのエンジニアインターンに参加。
MESON Works
MESONの制作実績一覧もあります。ご興味ある方はぜひ見てみてください。

Discussion