VRMアバターをVRで動かす
環境
- Unity 2021.3.5f1
- URP
- XR Interaction Toolkit 2.02
- UniVRM v0.102.0
- FinalIK ver2.1
FinalIKのインポート
- インポート時に発生したエラー
Problem detected while importing the Prefab file: 'Assets/Plugins/RootMotion/Shared Demo Assets/Props/Prefabs/MP-40.prefab'.
The file might be corrupt or have missing nested Prefabs. See details below.
Errors:
GameObject 'MP-40' does not reference component Animator. Fixing.
気持ち悪かったので該当箇所だけ除いて再度インポート(エラー無し)
VRIKの設定
初期設定
- XROrigin直下にアバターのGameObjectを移動
- アバターのGameObjectにVR IKコンポーネントをアタッチ
- Camera Offsetの下に、それぞれHead, LeftHand, RightHandのGameObjectを作成
- VR IKコンポーネントのSolverの下に、先ほど作成した3つのGameObjectを設定する
動かす
- 一応動いたが、視点がアバターの上部にあって自分のアバターを見下ろせてしまう
- 右手コントローラー、左手コントローラーを動かすと、アバターのそれぞれ対応した手が動く
- 調整する方法はまだ詳しく調べられていない
参考
VRIKの調整
環境
- Oculus Quest 2
- Build後、USBでapkファイルをQuestにコピーして単体で起動
デバッグメモ
以下GameObject = GOと略す
XR Origin(GO) > XR Origin(Component) > Tracking Origin ModeがDeviceの状態で
- Camera Offset(GO) > Main Camera(GO)の位置(Transform)は関係ない(Main CameraのTransformを大きく変更しても、アプリ起動後はXR Originの位置に戻っていた)
- [仮説1] Main Camera の位置がVR IKによって強制的に位置を変更されている?(Solverに合わせて、とか) => 疑問2によって否定されている
- [仮説2] Main Cameraの位置は、IKとは関係なく、XR Originの位置に合うように調整される?
- XR Origin(GO) > XR Origin(Component) > Camera Y Offsetは関係する(0だと床面、1だとアバターの頭と同じくらい、3だとアバターの頭上のかなり上の位置に視点が来る)
- これをアバターの身長に合わせて動的に設定すればよいのでは?
- 初期位置は、Questのホームボタン長押しでセットされる位置(アプリ起動時のQuestの位置ではない。Questのホーム画面から位置はそのまま引き継ぐ。アプリ内でホームボタン長押しによって位置リセットもできる)
疑問1: Camera Y OffsetとアバターのHead(ボーン)の両方が視点に影響している?
- [実験] アバターのy軸スケールを3倍(Headボーンの位置も伴って上がる)、XR OriginのCamera Y Offsetを1にした
- [結果] 視点はアバターy軸スケールが1倍のときと同じ。アバターは大きくなっている(が、自分の視点がアバターの顔の位置にあるか確認できず...。おそらく、大きくなったアバターがかがんでいる感じかな?
- [考察] 視点の位置はCamera Y Offsetで決まっている。アバターのHeadボーンは視点には影響していないが、HMDを傾けた際のアバターの体の動きに関係する
疑問2: Main Cameraとその直下のHead(GO)について
- そもそも、XR Origin > Camera Offset > Main Camera(GO)と、そのMain Cameraの直下のHead(GO)との関係性ってどうなってる?
- [実験] HeadのTransform yを1や3にしてみた
- [結果] 直立しているときは通常と変わらない位置に視点があったが、首を前後左右に傾けると、視点はその位置のまま、アバターが前後左右に移動した
- [考察]
- Main Camera: HMDの位置と、視点を管理している(両方とも該当コンポーネントがアタッチされているので当たり前なのだけどw)
- Main Camera直下のHead: VR IKによって、アバターのHeadボーンと対応付けられている。
- HMDが直立しているときには、Main Camera直下のHeadはy軸的にHMD(Main Camera)よりも上にいるはずだが、アバターの身長は伸びないので正しいように見えている。しかし首を傾けると、Headのxz平面座標の位置にアバターのHeadボーンが移動する(長い帽子を被っているイメージ。帽子の根本が視点、帽子の頂点がアバターの頭。)
ここまでの考察
- まずMain Cameraの位置が、XR OriginのCamera Y Offsetによって決まる。ここが視点。
- Main Camera > Headの位置が、アバターのHeadボーンの位置と対応する。
参考
- こりんさんブログ(トラッキングの位置基準について)
https://framesynthesis.jp/tech/unity/xr/#トラッキング基準位置について
VRIKの調整(続き、視点の調整)
- 視界が良好になるように位置を調整したい
1. アバター本体のTransformを、XR Originから大きくずらしてみる
-
下の写真でいう、Girl Aの位置
-
結果: 変わらない(起動したあとアバターが自分の視点の位置に戻ってくる)
2. Main Camera > Headの位置をずらした
- HeadがアバターのHeadボーンの位置にくるので、Main Cameraに対してHeadを後ろにずらせばよい
- 結果: 改善されたが、首を傾けたりするとまた顔の内側が見えてしまう
- これ沼そう。顔に内側を描画しないようにしたい
3. VRMの設定で可視設定を行う
が、VRM的にFirst Personと認識されていないのか、顔の内側は表示されたままだった。
4. 顔のmeshのLayerを手動で分け、Main CameraのCulling Maskで調整
- 顔は映らなくなった。
- しかし、動き方(後ろに移動したときなど)や顔の傾け方によっては髪の毛が移りこむ
- 今使用しているアバターは髪の毛のmeshが分かれていないことや、髪の毛が見えるのは不自然ではない可能性(VRCでも毛先は見える)もあるので、いったん保留。
- またちゃんとアバターを設定するときに戻ってきたい。
- 参考
https://qiita.com/but80/items/3cc28cd874764daf3e58
トラッキングのDeviceとFloorについてもあとで読んどこ
- VRChatでは、ユーザーの頭がアバターの頭より高い位置にあるときに、アバターが浮遊する(アバターが地面に固定されていない)
- 一方現状作っているアプリではアバターは地面固定なので変更する必要あり
DVRSDKを導入した
VRIKの設定
https://qiita.com/karukaru/items/b74bb5bdf08f5de32d0e
これみながらいじいじ
他のVRSNSの研究
VRChat
- sit/standに関係なく、腕の長さは入力した身長から計算している模様(これが自然。腕を伸ばしても途中でアバターの腕が伸びきってしまうことがない)
- アバターの大きさは一定
- sitにすると、実際にHMDの高さに下駄が履かせられる模様。standは現実世界での位置(なので、現実で座っている状態でstandにするとVR空間内では座っている)
DMM Connect Chat
- キャリブレーションを実行したときの現実世界でのHMDの高さが、VR空間内でアバターが立っている状態になるように調整される
- アバターの身長や手の長さが再計算されて、スケールが変わっている。
- 現実世界で座っている状態でキャリブレーションをすると、アバターが小さくなる(よって、腕の長さも短くなり、現実世界で手を伸ばしたときにアバターの手が先に伸びきってしまいついてこない問題が発生する)
いろいろ弄っても歩行アニメーションがどうしても気持ち悪いので、いったん Locomotion > ModeをAnimatedにして、足を動かなくしたら使えるようになったかも
いろいろまとめ
キャリブレーションすると
- アバターにコンポーネントとして
- VRIKが追加
- Wrist Rotation Fixが追加
- XROrigin(1階層上)配下に
- Head > HeadIKTarget(VRIKが参照)
- LeftHand > LeftHandIKTarget(VRIKが参照)
- RightHand > RightHandIKTarget(VRIKが参照)
- 最上位に
- PevisFollowObject(TransformFollowersがアタッチ済み、アバターボーンを追ってる)(VRIKが参照)
- LeftFootFollowObject(TFアタッチ) > LeftFootBendGoalTarget(VRIKが参照)
- RightFootFollowObjet(TFアタッチ) > RightFootBendGoalTarget(VRIKが参照)
Sceneを再生して、DoCalibrationを呼び出す前
- XROriginにアタッチされたOpen XR Trackerが、XROrigin以下のHead, LeftHand, RightHandを生成する
- この時点で、それぞれの直下にIKTargetはない
- 位置の管理は、Open XR Trackerがやっていそう
DoCalibrationを呼んだあとで、
-
PevisFollowObject, LeftFootFollow, RightFootFollowが生成
-
これらは位置の管理を自身にアタッチされたTransformFollowersが行っている
- camera offsetの高さは、Tracking Origin ModeをFloorにすると自動的に消去されてしまう
https://docs.unity3d.com/ja/Packages/com.unity.xr.interaction.toolkit@2.0/manual/general-setup.html#追跡対象デバイスに対する-xr-origin-カメラリグを作成する
[!ノート] ** Device** モードでは通常、XR ランタイムが空間内の固定位置 (開始時のヘッドマウントディスプレイ (HMD) の初期位置など) を基準として、追跡対象デバイスの位置を知らせます。このモードの場合は、XR Origin の Camera Y Offset を、Main Camera の地面からの高さに設定します。Floor モードでは通常、XR ランタイムはプレイヤーが立つ実際の床を基準として、追跡対象デバイスの位置を知らせます。このモードでは、必ずしも追跡の原点を人為的に上昇させる必要はないので、Camera Offset の高さは自動的に消去されます。デフォルトモードの XR ランタイムを使用するには、Not Specified モードに設定します。