概要
VRIK の歩行モーションに違和感があったので、自作した Animator の歩行モーションを使いたかったが、そのままだと腕と足の動きが VRIK に依存してしまっていたので記事に残すことにした。
環境
- Unity 2018.4.22f1
- Final IK version 1.8
手順
- 腕の Weight を 0 にする
- Locomotion の weight を 0 にする
- キャラクターの transform を更新し続ける
腕のweightを0にする
下記のようにしたいので、移動時のみ腕のweightを0にする。
止まっている時: VRトラッキング
歩いている時: Animator
スクリプトは下記の通り。
private void Update() {
if (_isWalk) ChangeVrikWiehgtForWalk();
else ChangeVrikWeightForIdle();
}
// 歩行時のVRIKウェイト設定
private void ChangeVrikWeightForWalk()
{
_vrik.solver.leftArm.positionWeight = 0f;
_vrik.solver.rightArm.positionWeight = 0f;
_vrik.solver.leftArm.rotationWeight = 0f;
_vrik.solver.rightArm.rotationWeight = 0f;
}
// 待機時のVRIKウェイト設定
private void ChangeVrikWeightForIdle()
{
_vrik.solver.leftArm.positionWeight = 1f;
_vrik.solver.rightArm.positionWeight = 1f;
_vrik.solver.leftArm.rotationWeight = 1f;
_vrik.solver.rightArm.rotationWeight = 1f;
}
Locomotionのweightを0にする
移動モーションは Animator で、transform の更新は自作スクリプトで行うので、Locomotion の weight は常に 0 に設定する。
private void Start() {
_vrik.solver.locomotion.weight = 0f;
}
キャラクターの transform を更新し続ける
Locomotion の weight を 0 にするとキャラクターがその場から動かなくなってしまうので、頭の position を使ってキャラクター本体の座標を更新し続ける必要がある。スクリプトは下記の通りで、適当な MonoBehaviour 継承クラスに記載する。
private void LateUpdate()
{
if (_vrik == null) return;
var d = _vrik.solver.spine.headTarget.position - _vrik.references.root.position;
d.y = 0f;
var mag = d.magnitude;
_vrik.references.root.position += d.normalized * mag;
}
参考記事
- FINAL IK - Full Body IK, Aim, Look At, FABRIK, CCD IK... [1.0 RELEASED] - Unity Forum
- Final IK の VRIK の Solver にある各値の説明 - Qiita
まとめ
調べても記事がほとんどなく、唯一見つかった UnityForum の記事を頼りに実装しました。
もっとクールな実装を知っている方がいらっしゃいましたら、コメントでご教示いただけますと幸いです。