Raspberlyのブログ

Raspberlyのブログ

Unityネタをメインとした技術系ブログです。にゃんこ大戦争や日常なども。そろそろブログタイトル決めたい

【Oculus Quest開発メモ】物を掴むとき位置と角度を固定する part2【Unity】

今回はOculus Questの開発ネタをやっていきます。
内容的にはOculus Rift Sなどにもそのまま応用できるかと思います。

OVR Grabberなどで物を掴んだ時に、位置と角度を固定する方法について紹介します。

 

 

 

本記事は過去の記事の追記バージョンになります。
前回の記事にこのようなフィードバックをいただきました。

改めて見直すと完全に説明不足でした。本当に申し訳ありません。
前回をベースにGifと解説を増やしてお送りいたします。SnapOffsetをNullにする方法です。

f:id:Raspberly:20190913020415p:plain




 

 

 

開発環境

Windows 10

Unity 2018.4.5f

Oculus Integration ver1.40

Oculus Quest

ALVR

※ALVRだと、物を掴んだ時に人差し指が正常にアニメーションしないことがあります。
本記事の画像やGifでもたびたびありますが、機能的には何も問題ありません。

 

 

セットアップ

開発環境を整えていない方は先にこちらをどうぞ。

raspberly.hateblo.jp

参考

Unity で Android アプリをビルドするには - フレームシンセシス

Unity+Oculus Quest 開発メモ - フレームシンセシス

 

 

 

 

 

サンプルシーンの確認+準備

基本的な掴む投げる動作を学ぶことができるAvatarGrabシーンを使います。
OVR Grabber、DistanceGrabber共に動くのでDistanceGrabシーンでも特に問題はありません。

f:id:Raspberly:20190911231416p:plain

 

手を出す

ALVRでやる場合はこちらを参考に手を用意しておきましょう。
CustomHandプレハブをシーンに置くだけです。

raspberly.hateblo.jp

 

Hand.csの修正も忘れずに

raspberly.hateblo.jp

 

 

 

 

 

3Dモデルの用意

前回に引き続き、刀と銃のアセットを使用します。
自前で3Dモデルをお持ちでしたらそちらで構いません。

刀アセット Wakizashi

 
高品質な刀です。AssetStoreまとめさんでも紹介されていました。

www.asset-sale.net

ハンドガンアセット

弾丸やマガジンも含まれたハンドガンのアセットです。

 

 

 

 



3Dモデルの配置

まずステージ内に先ほどインポートした、刀と銃を配置します。
その前に、目の前のテーブルが少し狭いので邪魔なオブジェクトは予め非アクティブにしておきましょう。

f:id:Raspberly:20190912000346g:plain

Wakizashiプレハブをシーンに置きます。

f:id:Raspberly:20190911231748p:plain

この時、空のGameObjectを作りその中にWakizashiプレハブを子オブジェクトとして登録しておきます。
こうすると後々楽になります。今回はKatanaという名前をつけました。

f:id:Raspberly:20190912001136p:plain

そのままだと垂直に置かれるため、PositionやRotationを変えて寝かせるといいでしょう。

f:id:Raspberly:20190912001203p:plain

f:id:Raspberly:20190911232354p:plain

ついでに、Wakizashiプレハブの子オブジェクトにある_Collidersは非アクティブにしておきます。

f:id:Raspberly:20190912002019p:plain



 

Handgun_M1911A_Blackプレハブをシーンに置きます。
この3Dモデルにはマガジン(弾倉)がついていません。
同じフォルダ内にあるM11911A_Magazine_Blackを子オブジェクトにしてあげるといい感じになります。

f:id:Raspberly:20190911233006p:plain

ただし、そのままシーンに置くとスケール感がまったく合わないためこちらもTransformを調整します。

f:id:Raspberly:20190912000322p:plain

f:id:Raspberly:20190911233552p:plain

 

 

コンポーネントのアタッチ

配置しましたら、必要なコンポーネントをアタッチしていきます。
必要なのはOVR GrabbableコンポーネントRigidbodyColliderです。

Katanaオブジェクトのインスペクターを以下のようにします。

f:id:Raspberly:20190912001906p:plain


Handgunプレハブに直接アタッチしていきます。

f:id:Raspberly:20190912002143p:plain

 

刀銃共にコライダーは適当につけています。細かい調整はSnap設定後にしましょう。

f:id:Raspberly:20190912002251p:plain

 

 

 

 

これで掴むことができます。
ここまではOVR GrabberとOVR Grabbableの復習を兼ねています。

この状態だと、オブジェクトのどこでも掴むことができるので、刀の刀身をそのまま掴めます。

 f:id:Raspberly:20190912005415g:plain

 

 

 

 

 

Snapの設定

ここからが本題です。Snap機能を追加します。
今回は刀の方をメインで行います。銃も同じ手順で設定できます。

OVR Grabbableの設定

まずは、刀、銃共にOVR GrabbableSnap PositionSnap Orientationにチェックを入れます。
Snap OffsetはNullのままです。 

f:id:Raspberly:20190912004939p:plain

 

次にUnityエディターのHandle PositionをPivotにしておきます。(標準だとPivotのはず)
ここはボタンになっていて切り替えることができます。

f:id:Raspberly:20190912005638p:plain

 

Colldierの設定

今までは親オブジェクトにColliderを付けていましたが、3Dモデルに沿った当たり判定を付けたいため、
親ではなくMeshRendererのついた子オブジェクトにColliderをつけます。(最初からこうしてもよかったかも)

KatanaオブジェクトのBoxColliderを無効化、あるいは削除します。

f:id:Raspberly:20190913005248p:plain

 

WakizashプレハブにBoxColliderをアタッチします。この時パラメータも自動でいい感じに設定してくれます。
また、最初からついているRigidbodyを削除します。最終的に↓のような感じ。

f:id:Raspberly:20190913005940p:plain


最後にKatanaオブジェクトのOVR GrabbableにあるGrabPointsにWakizashiプレハブのBoxColliderを紐づけます。

f:id:Raspberly:20190913010144p:plain



 

 

Snapする位置と角度(刀の場合)

Katanaオブジェクトを選択してシーンビューを見てみましょう。
XYZの矢印が表示されます(この矢印のことをGizmo(ギズモ)といいます)
ここがKatanaオブジェクトの原点座標です
Katanaの場合、鍔の部分が原点になっていますね。

f:id:Raspberly:20190912011132p:plain



先ほど、OVR GrabbableのSnap OffsetをNullのままにしましたが、
ここがNullだとSnapしたときの位置と角度はオブジェクトの原点座標と同じになります

試しにこの状態のまま動かしてみると、どこを掴んでも鍔の部分にSnapされているのがわかります。

f:id:Raspberly:20190912011037g:plain

 

 

3Dモデルの位置調整

刀の場合、MeshRendererコンポーネントがあるのはWakizashiプレハブです。
そのため、Wakizashiプレハブの座標を掴ませたい位置と角度に合わせて移動してあげます。

f:id:Raspberly:20190913010919g:plain

何度か実行してテストしながら、手にピッタリ合った位置と角度を見つけましょう。

 

 

効率的な調整方法

OculusQuestで毎回ビルドしながら位置角度調節するのはなかなか苦行です。
できることならRift SかALVRを使い、Unityエディター上で調整しましょう。その方が手っ取り早いです。

 

 

以下やり方を紹介

まず、エディター上で起動し、手に持ったところで一時停止します。
そうしたら、シーンビューでWakizashiプレハブをいい感じの位置と角度に調整します。

(キーボードのQWERTキーで、編集モードを変えていくとスムーズに調整できます)

f:id:Raspberly:20190913012515g:plain

 

 

無事調整できたら、この時点のWakizashiプレハブのTransform値をコピーします。
プレイモード解除後に値はリセットされますが、そこに先ほどコピーした値を上書きします。

f:id:Raspberly:20190913013151g:plain



これで手にフィットした形に、Wakizashiプレハブの位置と角度が設定されました。

f:id:Raspberly:20190913013424p:plain

最後にWakizashiプレハブのTransformは変えずに、親であるKatanaオブジェクトの位置を調整して完成です。

刀のどこを掴んでも、掴んだ瞬間位置と角度が矯正されます。

f:id:Raspberly:20190913014510g:plain

 

 

銃オブジェクトも同様に設定できます。

f:id:Raspberly:20190913020821g:plain

これで、掴んだ時の位置と角度を固定できるようになりました。 

 

 

 

 

 

まとめ

SnapOffsetはnullのまま、子オブジェクトの3Dモデルの位置を調整する

 

 

 

 

 

 

別の方法について

とても使いにくいことで評判のSnap Offsetですが、@udo_nbaさんが大変わかりやすい記事を投稿しています。

qiita.com

作るのが面倒なSnapOffsetを簡単に作る方法を解説しています。
こちらも参考にしてみてください。

 

 

 

 

 

わかりにくい所、間違っている箇所がありましたらコメントにお願いします。
特に、「ここがよくわからん」「それどうやってるの?」「そんな項目ないんだが」など
詰まる箇所がありましたらドシドシコメントに書き込んでください。よろしくお願いします。