Meta XR SDKで3Dオブジェクトをつかむ方法(GrabInteractor、Grabbableなど)

こんにちは、くのへ@MasazaneKunoheです。

今日はMeta XR SDKで3Dオブジェクトをつかむ方法を解説します。
3DオブジェクトをつかめるとVRの力を感じてとても感動しますよ!(マジで)
特にパススルー状態で物をつかむとMRを心の底から感じます!!

はじめに

この記事はMeta XR SDKを使って、3Dオブジェクトをつかむ方法を解説します。
これを習得すると、次の動画のようにものをつかむことが出来るようになります。
ただし、両手でつかんでびよーんとしたり、投げる動作はこの記事の内容だけでは出来ません。これらは別の記事で解説します。

開発方法

①準備

まずは、こちらの記事でパススルー機能ありの状態か、こちらの記事でパススルー機能無しの状態まで準備を進めて下さい。

②OVRInteractionを追加する

プロジェクトウィンドウでOVRInteractionを検索し(下図②③④)、OVRCameraRigの子オブジェクトとしてこれを追加します(下図①)。なお、プロジェクトウィンドウのSearchはAllにしないと出てこないので注意してください(下図③)。

プロジェクトウィンドウで「OVRHands」を検索し、今追加したOVRInteractionの子オブジェクトとして追加します(下図①②③)。
このOVRHandsがハンドトラッキングで物をつかむことをコントロールします。

同様に、プロジェクトウィンドウで「OVRControllers」を検索して、OVRInteractionの子オブジェクトとして追加します(下図①②③)。これがハンドデバイスで物をつかむことをコントロールします。

今入れたOVRControllersを開き、
LeftController > OVRControllerVisal > OVRControllerPrefab
を選択し、インスペクターウィンドウのOVR Controller HelperコンポーネントのControllerをL Touchにしましょう。(下図①②)
同様に右手についても同じ操作(設定はR Touch)を行います。

③ハンドトラッキングにGrabInteractorを追加する

先ほど追加したOVRHandsを展開し、LeftHandとRightHandの中の「HandInteractorsLeft(Right)」を見つけましょう。このオブジェクトがInteractor類を保存するためのオブジェクトです。(下図①)
ここに、プロジェクトウィンドウで「HandGrabInteractor」を検索して追加しましょう(下図②③)。(左手だけではなく右手にも追加しましょう)

なお、3Dオブジェクトを操作する側をInteractor、操作される側をInteractableと言います。
VRデバイスやハンドトラッキング側に前者を、Cubeなどの3Dオブジェクトに後者をアタッチすれば操作できる仕組みになっています(これはMeta XR SDKだけではなく、XR Interaction Toolkitでもこのような仕組みになっています)。
上記はOVRHandsにInteractorを付ける設定を行ったので、ハンドトラッキングで3Dオブジェクトをつかめるように設定をしているというものです。

さて、今 設置したHandGrabInteractorを選択し、Inspectorを確認し、Hand RefにLeftHandが設定されていることを確認しましょう(下図①②)。右手も同様に確認しましょう(下図③)。
もしも設定されていなければ、ヒエラルキーウィンドウのOVRHands直下のLeftHand(またはRightHand)のオブジェクトをHand RdfのHandのところにドラッグアンドドロップすれば設定できます。

更に、HandGrabInteractorの一つ上位のHandInteractorsLeft(またはRight)をクリックし(下図①)、今設定を行ったHandGrabInteractorをインスペクターウィンドウのBest Hover Interactor GroupのInteractorsの文字のあたりにドラッグアンドドロップしましょう(下図②)。
すると下図の通りInteractorsのElement0としてHandGrabInteractorが設定されます(下図②)。これで、ハンドトラッキングで親指と人差し指をつまむ動作を行うと「Grab(つかむ)」が効くようになります。このアタッチを忘れてしまうとGrabが動かないのですが、忘れやすいので注意しましょう。
これを右手も同様の操作を行いましょう(下図③)。

これでハンドトラッキングのInteractorの設定は完了です。(注:まだ捕まれる側の設定が終わっていないので何もつかめません。)
ただし、もともとのハンドトラッキング(OVRHandPrefab)の手のレンダリングと、今回追加したOVRHandのレンダリングが両方生きており、2重でレンダリングされてしまうので、OVRHandPrefab側のレンダリングの機能を停止しておきましょう(下図①②③④⑤⑥)。
具体的には、OVRCameraRig>TrackingSpace>LeftHandAnchor>OVRHandPrefabの次のコンポーネントのチェックを外して機能をOFFにしておきます。
-OVR Skeleton(下図②)
-OVR Skeleton Renderer(下図③)
-OVR Mesh(下図④)
-OVR Mesh Renderer(下図⑤)
-Skinned Mesh Renderer(下図⑥)
これを左手だけではなく右手も行いましょう(下図⑦)。

これでハンドトラッキングの設定はOKです。

次にハンドデバイスのInteractorの設定を行います。
プロジェクトウィンドウで「ControllerGrabInteractor」を検索し、
 OVRInteraction > OVRControllers > LeftControllerInteractors
の中に入れます。(下図①②)
右手も同様に「ControllerGrabInteractor」を追加します(下図③)。

なお、ControllerGrabInteractorをControllerInteractorsの子オブジェクトとしてセットすると、ControllerGrabInteractorの有するController Refコンポーネントが反応して左右のコントローラを自動的に参照します。そのためハンドトラッキングの時のように手動で左右を指定する必要はありません。

さて、いまセットしたControllerGrabInteractorの親オブジェクトであるControllerInteractorsをクリックし、Best Hover Interactor GroupのInteractorsにControllerGrabInteractorをドラッグアンドドロップしましょう(下図①②)。これで、コントローラの中指のグリップボタンでGrabが効くようになります。このアタッチを忘れてしまうとGrabが動かないのですが、忘れやすいので注意しましょう。
右手についても同様の設定をしましょう(下図③)。

以上でハンドデバイスの設定も完了です。お疲れ様でした。
ただし、これでもオブジェクトはつかめません。それは、「つかまれる側」の設定をしていないためです。
次の項でつかまれる側の設定を行います。

④つかまれる側の設定を行う

1)準備

つかまれる側にも設定が要ります。今回は解説のために次の準備を行いました。
-Cubeで赤いDeskを作成。
-その上に、緑・青・黄色の小さなCubeを作成。
 名前はCube(green)、Cube(blue)、Cube(yellow)としました。
-このCube(green)、Cube(blue)、Cube(yellow)すべてにRigidbodyを追加。
(下図①②③参照)

これで準備はOKです。この緑・青・黄色のCubeに「つかまれる設定」を行います。

2)つかまれる設定

・基本設定

まず共通項目として、この緑・青・黄色のCubeに次のコンポーネントを追加します。
-Grabbable
-Physics Grabbable

この二つは非常に重要かつ基本的なコンポーネントになります。
◆Grabbable
Grabbableは「つかまれたこと」をコントロールするメインプログラムです。こいつは絶対に必要です。良く分からなくても呪文だと思ってセットしましょう。
◆PhysicsGrabbable
PhysicsGrabbableはつかまれた物体につかんだ側(:ハンドトラッキングやハンドデバイス)の物理演算データを正しく引き渡します。こいつがセットされていないと、色々と変な挙動を示します。例えば、PhysicsGrabbableをアタッチしていない状態で、3Dオブジェクトをつかみ、そして離すと、離した瞬間に対象物がぶっ飛んでどこかに消えてしまいます。
これは、つかむ側(ハンドトラッキングまたはハンドデバイス)のColliderと、つかまれる側(Cubeとか)のColliderが離した瞬間は深く接触している状態になっているので、ぶっ飛んでしまうのです。
このぶっ飛びを防ぐために、RigidbodyのIsKinematicをONにするという方法もあるのですが、それだと離した瞬間にその位置で動かず、重力も効かないので、ちょっとイマイチです。
PhysicsGrabbableを付けると、離した瞬間のぶっ飛びは回避され、自然な感じに動きます。
別な記事で記載しますが、ものを投げる、、、すなわちハンドトラッキングやハンドデバイスの速度をつかまれた3Dオブジェクトに引き渡す設定を行う際にもPhysicsGrabbableを使います。
このように色々と御利益があるので、PhysicsGrabbableはGrabbableと一緒に設定する、と覚えておきましょう。

・Hand Grab Interactable

黄色Cube(Cube(yellow))を選択し、インスペクターウィンドウの一番下の「Add Component」を押して、「HandGrabInteractable」を検索してセットします(下図①②)。

これで、ハンドトラッキングでつかめるようになりました!!おめでとう!!

・Grab Interactable

次に、青Cube(Cube(blue))を選択し、インスペクターウィンドウのAdd Componentをクリックして「Grab Interactable」を検索して追加します(下図①②)。
これで設定完了、と思いきや、Grab Interactableはもうひと手間かける必要があります。
これは緑Cubeと一緒に操作するので、次に進んで下さい。

・両方設定する

緑Cube(cube(green))はHandGrabInteractableとGrabInteractableの両方をセットしましょう。(下図①②)。

先ほどいったん置いておきましたが、Grab Interactableはもうひと手間×必要があります。
Cube(blue)を選択し、インスペクターウィンドウのGrab Interactableを見てみましょう。
Pointable ElementとRigidbodyがnoneになっていると思います。ここに、ヒエラルキーウィンドウのCube(blue)自身をドラッグアンドドロップしましょう。するとそれぞれ適切なコンポーネントがここにアタッチされます。(下図①)
同じくCube(green)のGrab Interactableにも同じ処理を行ってください。(下図②)
この処理を行わないと、ハンドデバイスでつかめません。

ちなみに、HandGrabInteractableは、このPointable ElementとRigidbodyが自動的に設定されていると思います。HandGrabInteractableはアタッチしたオブジェクトを自動設定する仕組みが働いている模様です。
じゃあ、、、なんで、GrabInteractableは自動設定にしなかったんだ、、、これもう分かんねーなw。

VRデバイスで実行してみましょう

この状態で、ビルドしてVRデバイスで見てみたものが冒頭の動画になります。

この動画の通り、黄色Cubeはハンドデバイスではつかめませんが、青・緑Cubeはつかめています。
ハンドトラッキングでは、青Cubeはつかめませんが、黄・緑Cubeはつかめているのが分かると思います!

なお、動画でアピールしていますが、両手でつかんだら全く動かなくなります。
これは、デフォルトでは片手で動かすことが出来る設定が働くのですが、両手でつかんだ場合は全く設定されていないので何も動かなくなるというものです。

両手での操作については次回の記事で解説します!!


今日はMeta XR SDKで3Dオブジェクトをつかむ方法(GrabInteractor、Grabbableなど)を紹介しました。
物がつかめると感動しますよ!
特にパススルー状態で物がつかめると、本当にMRを感じることが出来ます。

ではまた別の記事で会いましょう。
ではでは~

🦅バサバサ~