Raspberlyのブログ

Raspberlyのブログ

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

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

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

 

銃などを掴む時、取っ手やグリップなど特定のポイントを握るようにしたいと思うことがあると思います。
そういう時はGrabbableについているSnap機能を使うと便利です。 
今回は、とても使い方がわかりにくいことで評判のSnapOffsetについて解説していきます。

f:id:Raspberly:20190624002232p:plain



 

 

2019年9月13日追記

よりわかりやすく解説した補足記事を投稿しました。
こちらも合わせてどうぞ。

raspberly.hateblo.jp

 

 

 

 

 

 

開発環境

Windows 10

Unity 2018.4.1f

Oculus Integration ver1.37

Oculus Quest

 

 

 

 

セットアップ

このメモは前回の続きとなります。
まだの方は先にこちらからどうぞ。

raspberly.hateblo.jp

 

 

使用アセット

今回使用したアセットを紹介します。

刀アセット Wakizashi

f:id:Raspberly:20190623233924p:plain

http://u3d.as/1vSL
高品質な刀です。AssetStoreまとめさんでも紹介されていました。

www.asset-sale.net

ハンドガンアセット

f:id:Raspberly:20190623234141p:plain

http://u3d.as/1jZw

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

 

 

 

 

 

 

サンプルシーンの確認

Assets/SampleFramework/Usageに様々なサンプルシーンがあります。
今回も前回と同じAvatarGrabシーンを改造していきます。

が、今回のSnapOffset機能はDistanceGrabシーンで活用されているのでそちらも併せてどうぞ。

raspberly.hateblo.jp

 

 

 

 

物を持つ時に特定の場所を掴んでほしい

前回の記事では物を持った時にGrabbableのコライダーの範囲内であればどこでも掴んで持つことができました。
しかし、銃や刀のように掴んでほしい位置や角度が明確である場合どうすればいいでしょうか。
刀の場合、刀身部分を掴めるのはあまり好ましくありません。柄を握ってほしいはずです。

f:id:Raspberly:20190623191401g:plain

 

そこで、OVR Grabbable及びDistance Grabbableには物を掴んだ時に位置や角度を矯正する機能があります。
その機能がSnapOffsetです。

 

 

 

OVR Grabbable

OVR Grabbableコンポーネントを見てみると、
SnapPositionとSnapOrientationの項目が確認できます。
ここにチェックを入れると掴んだ時に、SnapOffsetの所に入っているTransformに合わ移動します。

f:id:Raspberly:20190608224838p:plain

 

 

 

 

 

 

 

Snap Offset

このSnapOffsetのTransformの設定ですが、まずOVR Grabbableな3Dオブジェクトに、
掴んでほしいポイントを示す空のゲームオブジェクトを子オブジェクトにする。

f:id:Raspberly:20190623195155p:plain



f:id:Raspberly:20190623190439p:plain

そしてこの空のゲームオブジェクトをSnapOffsetとして登録すれば掴んだ時に位置や角度が矯正されます。

f:id:Raspberly:20190623195233p:plain



 

・・・と思った方が多いかと思います
実はこのやり方は間違いです。

 

 

この手順だと正常にスナップされません。
掴んだ時に位置や角度がおかしな場所になります。

f:id:Raspberly:20190623201114g:plain



 

 

 

 

 

Snap Offsetの本当の使い方

UnityForumの方にもこの問題点が取り上げられていました。

https://forum.unity.com/threads/vr-oculus-sdk-touch-controller-snap-position-snap-offset-grab-a-gun.512853/

正しい使い方は以下に記しますが全く直感的ではない使い方です。

 

Snap Offsetの正しい使い方

1. Unityのシーン内のPosition(0, 0, 0)、Rotation(0, 0, 0)の場所に空のゲームオブジェクトをつくります

f:id:Raspberly:20190623202917p:plain

2. このオブジェクトを矯正させたい位置や角度分だけ値を変更します

f:id:Raspberly:20190623210751p:plain

3. このオブジェクトをSnapOffsetとして登録します

f:id:Raspberly:20190623195233p:plain

以上となります。

 

 

実際にOffsetさせてみる

上記の手順通りに実際にやってみます。
まずはPosition、Rotationともに0のゲームオブジェクトを作り、これをSnapOffsetとしてみます。

f:id:Raspberly:20190623202917p:plain

 

最初のやり方と違い無事手にスナップされました。
Position、Rotationが0の場合はこうなります。

f:id:Raspberly:20190623213318g:plain



次にRotationを変えてみます。Xを-60にしました。

f:id:Raspberly:20190623210751p:plain

すると、掴んだ時の角度が矯正されます。

f:id:Raspberly:20190623213455g:plain

これをひたすら動作確認しながら調整する必要がありますが非常に面倒です。

 

 

 

 

 

 

ベストプラクティス(このやり方がオススメ)

ここのベストプラクティスを@nkjzmさんが紹介していました。

 

結論からいいますと、Snap OffsetはNullのまま
掴みたいオブジェクトのレンダラーの座標や角度を調整します

 

銃の場合ですと、Grabbableがアタッチされている親オブジェクトはそのままに、
子オブジェクトの銃の3Dモデルの位置を調整します。

f:id:Raspberly:20190623223015p:plain

 

剣の場合はこちら、剣はRorationのxを-60にするといい感じになります。

f:id:Raspberly:20190623223205p:plain

実際に動作確認して細かく調整する必要はでてきます。

 

 

これで完成です。きちんと手の形に収まるようになりました。
刀を見てみると、刀身を掴もうとしても柄の部分に矯正されているのがわかると思います。

f:id:Raspberly:20190623225845g:plain

 

 

 

 

 

 

まとめ

SnapOffsetはnullのまま、3Dオブジェクト側の座標を調整しよう

 

 

 

 

 

参考資料

 

qiita.com

 

 

 

 

 

 

他間違っている箇所がありましたらコメントにお願いします。