MRが楽しい

MRやVRについて学習したことを書き残す

UnityのIK(インバースキネマティクス)を使ってアバターの手足を動かす

本日は Unity の技術調査枠です。
UnityのIK(インバースキネマティクス)を使ってアバターの手足を動かしてみます。
f:id:bluebirdofoz:20210905225443j:plain

IK(インバースキネマティクス)

ジョイントのポージングを行う際、空間の目標座標から逆算してジョイントの向きを決定する機能です。
本機能は Humanoid キャラクターの Mecanim でサポートされます。
docs.unity3d.com

サンプルプロジェクト

IK の機能を試すため、Unity プロジェクトを作成しました。
シーンに Humanoid リグを設定したキャラクターモデルを配置しています。
f:id:bluebirdofoz:20210905225511j:plain

今回は以下の記事で取得した Y-Bot モデルを利用しています。
bluebirdofoz.hatenablog.com

IKを有効化したアニメーションコントローラの作成

IK を利用するには IKPass を設定したアニメーションコントローラが必要です。
[Create -> ]でアニメーションコントローラを作成します。
f:id:bluebirdofoz:20210905225527j:plain

作成したアニメーションコントローラに State を作成し、適当なモーションを設定します。
ここでは Y-Bot モデルに含まれていたTポーズのアニメーションを設定しています。
f:id:bluebirdofoz:20210905225538j:plain

[BaseLayer]の歯車アイコンをクリックしてメニューを開き、[IK Pass]にチェックを入れます。
チェックを入れると[BaseLayer]に[IK]マークが付きます。
f:id:bluebirdofoz:20210905225550j:plain

これで IK を利用可能なアニメーションコントローラを作成できました。
Y-Bot モデルの[Animator]コンポーネントに作成したアニメーションコントローラを設定しておきます。
f:id:bluebirdofoz:20210905225600j:plain

サンプルスクリプトの作成

指定したトランスフォームを目標座標として、IK で右足のポーズを変更するサンプルスクリプトを作成しました。
・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 LegIKTarget;

    void Start()
    {
        // Animatorの参照を取得する
        p_Animator = GetComponent<Animator>();
    }

    void Update()
    {

    }

    // IK更新時に呼ばれる関数
    // IKPassにチェックを入れた場合のみ呼び出される
    void OnAnimatorIK()
    {
        if (LegIKTarget == 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, LegIKTarget.position);
        p_Animator.SetIKRotation(AvatarIKGoal.RightFoot, LegIKTarget.rotation);
    }
}

f:id:bluebirdofoz:20210905225614j:plain

以下が IK の設定箇所になります。

// 右足のIKを有効化する(重み:1.0)
p_Animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1.0f);
p_Animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1.0f);

// 右足のIKのターゲットを設定する
p_Animator.SetIKPosition(AvatarIKGoal.RightFoot, LegIKTarget.position);
p_Animator.SetIKRotation(AvatarIKGoal.RightFoot, LegIKTarget.rotation);

因みに IK の終点には右手、左手、右足、左足が指定できます。
docs.unity3d.com

スクリプトを Animator コンポーネントと同じオブジェクトに設定します。
f:id:bluebirdofoz:20210905225623j:plain

目標座標の指定

目標座標として、Cube オブジェクトをシーンに作成して配置します。
f:id:bluebirdofoz:20210905225634j:plain

配置した Cube オブジェクトをターゲットとしてスクリプトに参照を設定します。
これで準備は完了です。
f:id:bluebirdofoz:20210905225644j:plain

動作確認

シーンを再生して動作を確認します。
右足が Cube オブジェクトの位置になるようにポーズが変形すれば成功です。
f:id:bluebirdofoz:20210905225705j:plain

より細かくポーズを調整する

膝の向きなどより細かくポーズを調整したい場合は更にヒントポジションを利用します。
bluebirdofoz.hatenablog.com