
UnityでVRゲーム製作!XR Interaction Toolkit 物を持つ編
どうも皆様 Hello world!
Unityでゲームを作っております、天野スズランと申します。
Unityの「XR Interaction Toolkit」でVR開発をする方法を書いていきたいなぁと思ってますので、皆様どうかお付き合いください。
今回やること
今回は、物を持つ機能を実装しようかなと思ってます。
やっぱりVRゲームの面白さって、現実に近い形で物が持ててこそだと思うんですよ。ですから、今回はそれをやります。
なお、VRゲーム作成のためののセットアップの前々回と、移動およびターンの前回の続きになります。
よろしければご覧ください。
XR Interaction Manager の作成
物を持つためには、手などの"持つ側"と、道具などの"持たれる側"の二つが必要というのは分かりやすいと思います。
ですけど、「XR Interaction Toolkit」にはもう一つ、”その二つを結びつけるもの”が必要です。
それがこの「XR Interaction Manager」。
作るのが楽ですし、まずはこれを作っておきましょう。
「Hierarchy」に空のオブジェクトを作って、名前を「XR Interaction Manager」に変更します。
そして、「Add Component」から「XR Interaction Manager」を追加します。

追加後の設定などはいりません。これで完了です。
"持つ側"の作成
次は Interactor をつくって行きましょう。これは"持つ側"になります。
つまりは手を作って行きましょうという事ですね。
持ち方を選ぶ
さて、実際につくって行く前に、一つ決めなければいけないことがあります。「どうやって持つか」です。
この XR Interaction Toolkit では、二つの持ち方を選べます。
1つ目は、手の近くの物を持つやり方。
自分の手の周りに当たり判定があって、そこに触れたものを手に持てるというやり方です。
実際の手に近いやり方ですね。
Direct Interactor と名前がついているみたいです。

二つ目は、手から伸びたビームに当たったものを持つやり方。
自分の手からビームのようなものが伸びていて、そのビームに当たったものを手に持てるというやり方です。
ビームの長さは調節可能で、かなり遠くのものも持てます。
取り落とした銃をしゃがまなくても拾い直せるのは、結構ありがたいです。
こちらは Ray Interactor という名前のようです。

なお、表示を消すこともできます。
後々変える事も出来ますが、どちらで作るかは決めておきましょう。
なお、記事中では Direct Interactor で作って行きます。
手の作成
では、実際に手をつくっていきましょう。
Camera Offset の下に、Direct Interactor を作ります。
「XR Origin」→「Camera Offset」を右クリックし「XR」→「Direct Interactor (Action-based)」を押しましょう。

なお、Ray Interactor で作りたい場合「Ray Interactor (Action-based)」を選びましょう。

なお、Direct (Ray) Interactor は、二つ作りましょう。
それぞれ、右手と左手になります。
ついでに、名前もそれっぽく変えておきましょう。

なお、手の当たり判定の範囲をいじりたい場合は、「Sphere Collider」の「Radius」をいじりましょう。
0.1となっている場合は半径0.1mです。これを10とかにすると、半径10mにあるものを掴んでくれます。

入力の設定
次は、VR機器のコントローラーの入力を受け取る設定をしていきます。
まずは左手から。
「Project」ウィンドウの「Assets」→「Samples」→「XR Interaction Toolkit」→「2.0.0-pre.7」→「Default Input Actions」→「XRI Default Left Controller」を、「LeftHand Direct Interactor」オブジェクトの「XR Controller (Action-based)」へとドラッグ&ドロップしましょう。

右手も同じように設定しましょう。
「XRI Default Right Controller」を「RightHand Direct Interactor」オブジェクトの「XR Controller (Action-based)」へとドラッグ&ドロップです。
手を見えるようにする
今のままだと、手がどこにあるんだか分かりません。
ですので、とりあえず手の代りに球体を表示しておきましょう。
「Hierarchy」ウィンドウを右クリック、「3D Object」→「Sphere」を選択しましょう。

それから、名前を変えておきましょう。 Hand などにしておくと分かりやすいです。
それと、そのままだと手としては大きすぎますから、大きさをいじりましょう。
「Inspector」ウィンドウの「Transform」→「Scale」を0.05くらいにしておきましょう。こうすると、直径0.05mの球体になります。

じゃないと手として表示したときにおかしくなります。
それから、このオブジェクトはあくまで見た目の担当です。
見た目だけのものが何かに衝突しては困りますので、衝突判定をしないようにしましょう。
衝突判定をしているのが「Sphere Collider」ですので、それを右クリックし「Remove Component」で削除しておきましょう。

次は、今作った球体を「プレハブ」にしましょう。
「Hierarchy」ウィンドウにある球体を、「Project」ウィンドウの「Assets」の中にドラッグ&ドロップ。それでプレハブ化できます。

なお、今後使うのはAssetsに入れたほうのオブジェクトです。「Hierarchy」上の球体は削除しておきましょう。
そして、「Project」ウィンドウの中の「Hand」を、「LeftHand Direct Interactor」の「Model Prefab」へと設定しましょう。

これで、左手のあるところに「Hand」を表示させることができます。
同じように RightHand の方もやっておきましょう。
以上で"持つ側"の設定は終了です。お疲れさま。
"持たれる側"の作成
では次は"持たれる側"の設定です。
今回は、とりあえず丸いボールでも持ちましょう。
持たれるオブジェクトを作成
「Hierarchy」に「Sphere」を作り、Scaleを 0.1, 0.1, 0.1 くらいに設定しておきましょう。
詳しくは「手を見えるようにする」の所を見てください。
Interactable を追加
作ったボールの「Inspector」ウィンドウの「Add Component」をクリック、「XR Grab Interactable」を追加しましょう。

このコンポーネントを追加することで、追加されたオブジェクトが掴めるようになります。
当たり判定の設定
しかし、そのままだと移動がバグります。
何故かというと、プレイヤーの当たり判定とボールの当たり判定がぶつかって、離れようとしちゃうからですね。

これを解消するために、プレイヤーとボールがぶつからないようにしましょう。
オブジェクトにはレイヤーを設定する事が出来ます。
このレイヤーというのが何かというと、当たり判定の種類だと思ってください。「これはプレイヤー」とか「これはアイテム」とか「これは地面」とか。
で、その種類ごとに接触する相手を選べます。
プレイヤーと地面は接触する、アイテムと地面は接触する、けどプレイヤーとアイテムは接触せずすり抜ける、とか。
ですから、それを利用して反発しないようにしましょう。
まず、プレイヤーとなる「XR Origin」の「Layer」をクリックして「Add Layer」を選びましょう。

次に、適当に開いているところを選んで「Player」と入力しましょう。
これで、新しいレイヤーが出来ます。

その後改めて「Layer」から「Player」レイヤーに設定しましょう。
なお、ウィンドウが出てきて「子供になってるオブジェクトも一緒に変えとくか?」と聞いてきますが「いいえ」と答えましょう。
でないと、手の判定もPlayerに設定されて、手とボールが接触しなくなっちゃうので、持てなくなってしまいます。

同じように、持たれる側のボールも設定しましょう。
同じような手順で「Item」レイヤーを追加、ボールのレイヤーをそれに変えます。

それから、「Player」と「Item」が衝突しないように設定します。
画面上のメニューバー「Edit」から「Project Settings」を開き「Physics」を選択します。
ずっと下にスクロールしていくと「Layer Collision Matrix」という項目があるので、「Player」と「Item」が交わっているところのチェックを外しましょう。

これで設定が完了しました。移動がバグることがなくなります。
最後に
続きもそのうち上げていきたいです。次回は「銃を撃つ」の予定。
それから、一応Vtuberやってますので、気が向いたらフォローしてやってください。
たまーにつぶやいて、ごく稀に配信してます。
Twitter:@Suzuran_Amano
Youtubeちゃんねる:スズランちゃんねる - YouTube
この記事が、あなたの開発の助けになることを祈っています。