本日は Unity の技術調査枠です。
UnityのIK(インバースキネマティクス)を使ってアバターの手足を動かしてみます。
前提条件
本記事は前回記事の調査の続きです。
bluebirdofoz.hatenablog.com
ゴールポジションのみ設定した場合の動作
前回作成したプロジェクトを再生し、目標座標となるゴールポジションに指定したオブジェクトをモデルの横に移動してみます。
すると以下の通り、IK はちゃんと機能していますが、キャラクターが不自然に内股になってしました。
このようにゴールポジションの設定のみでは、膝や肘といったジョイント部分の向きを調整することができません。
ヒントポジションの設定
膝や肘の方向を設定するにはヒントポジションの座標を設定する必要があります。
以下の重み付けと座標指定の関数が利用できます。
docs.unity3d.com
docs.unity3d.com
なお、ヒントポジションは座標(Position)の指定のみで回転(Rotation)の指定はありません。
ヒント位置には右肘、左肘、右膝、左膝が指定できます。
docs.unity3d.com
サンプルコード
前回のスクリプトを以下の通りに修正し、ヒントポジションを指定できるようにしました。
・LegIKTest.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(Animator))] public class LegIKTest : MonoBehaviour { private Animator p_Animator; [SerializeField, Tooltip("LegIKのゴールターゲット")] private Transform LegIKGoalTarget; [SerializeField, Tooltip("LegIKのヒントターゲット")] private Transform LegIKHintTarget; void Start() { // Animatorの参照を取得する p_Animator = GetComponent<Animator>(); } void Update() { } // IK更新時に呼ばれる関数 // IKPassにチェックを入れた場合のみ呼び出される void OnAnimatorIK() { if ((LegIKGoalTarget == null) || ((LegIKHintTarget == null))) return; // IKゴールを有効化する(重み:1.0) p_Animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1.0f); p_Animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1.0f); // IKゴールのターゲットを設定する p_Animator.SetIKPosition(AvatarIKGoal.RightFoot, LegIKGoalTarget.position); p_Animator.SetIKRotation(AvatarIKGoal.RightFoot, LegIKGoalTarget.rotation); // IKヒントを有効化する(重み:1.0) p_Animator.SetIKHintPositionWeight(AvatarIKHint.RightKnee, 1.0f); // IKヒントルのターゲットを設定する p_Animator.SetIKHintPosition(AvatarIKHint.RightKnee, LegIKHintTarget.position); } }
新たにヒントポジションとなる Sphere オブジェクトを追加し、スクリプトに参照を設定しました。
これで準備は完了です。
動作確認
シーンを再生して動作を確認します。
ゴールポジションをモデルの横に移動します。
この時点ではヒントポジションが内側寄りのため、膝は内股のままです。
ヒントポジションも外側に移動してみます。
すると膝の向きがそちらを向くようになり、脚を開くようなポーズに調整できました。