Version: Unity 6.0 (6000.0)
言語 : 日本語
ヒューマノイドアニメーションのリターゲティング
ルートモーションの仕組み

IK

ほとんどのキャラクターアニメーションは、スケルトンのジョイントの角度を事前定義した値に回転させて作成します。子ジョイントの位置は、親の回転に応じて変化します。ジョイントチェーンの終了点は、チェーンに沿う個々のジョイントの角度と相対位置によって決まります。このスケルトンのポージング方法は フォワード キネマティクス と呼ばれます。

ただし、逆の視点からジョイントの配置を行うと便利な場合が多くあります。空間内の選択した位置や目標から開始し、終了点がその目標に到達するように逆算してジョイントの方向を決めます。これは、キャラクターにオブジェクトを掴ませたり、平らでない場所に立たせたりする場合に便利です。このアプローチは インバースキネマティクス (IK)と呼ばれます。Mecanim では、アバターが正しく設定されたヒューマノイドキャラクターでこの機能をサポートしています。

キャラクターに IK を設定する場合、通常、シーンの周囲にキャラクターが相互作用するオブジェクトがあります。これらのオブジェクトとキャラクターを使用し、スクリプト内に IK を設定できます。以下の Animator 関数を使用できます。

例えば、上の画像は、キャラクターがシリンダーオブジェクトに触れている様子を示しています。IK とスクリプトを使用してこれを行うには、以下の手順に従います。

  1. キャラクターに有効なアバターを作成します。
  2. 次に、キャラクターのアニメーションを少なくとも 1 つ含む Animator Controller を作成します。
  3. 次に、Animator ウィンドウの Layers ペインで、Base Layer の歯車のアイコンをクリックし、コンテキストメニューの IK Pass チェックボックスを有効にします。有効にすると、IK Pass は OnAnimatorIK コールバックを送信します。後のステップでは、このコールバックを使用してスクリプトにインバースキネマティクスを実装します。

デフォルトレイヤーの IK Pass チェックボックスを有効に設定

  1. キャラクターの Animator コンポーネントに Animator Controller が割り当てられていることを確認してください。

  1. 次に、キャラクターにスクリプトを追加します。この例では、スクリプトの名前は IKControl です。このスクリプトは、キャラクターの右手に IK ターゲットを設定します。また、このスクリプトは、キャラクターがシリンダーオブジェクトを掴んだときにそのオブジェクトを見るよう視線も変更します。以下にスクリプト全体を示します。
using UnityEngine;
using System;
using System.Collections;

[RequireComponent(typeof(Animator))]
public class IKControl : MonoBehaviour {

    protected Animator animator;

    public bool ikActive = false;
    public Transform rightHandObj = null;
    public Transform lookObj = null;

    void Start ()
    {
        animator = GetComponent<Animator>();
    }

    //a callback for calculating IK
    void OnAnimatorIK()
    {
        if(animator) {

            //if the IK is active, set the position and rotation directly to the goal.
            if(ikActive) {

                // Set the look target position, if one has been assigned
                if(lookObj != null) {
                    animator.SetLookAtWeight(1);
                    animator.SetLookAtPosition(lookObj.position);
                }

                // Set the right hand target position and rotation, if one has been assigned
                if(rightHandObj != null) {
                    animator.SetIKPositionWeight(AvatarIKGoal.RightHand,1);
                    animator.SetIKRotationWeight(AvatarIKGoal.RightHand,1);  
                    animator.SetIKPosition(AvatarIKGoal.RightHand,rightHandObj.position);
                    animator.SetIKRotation(AvatarIKGoal.RightHand,rightHandObj.rotation);
                }

            }

            //if the IK is not active, set the position and rotation of the hand and head back to the original position
            else {          
                animator.SetIKPositionWeight(AvatarIKGoal.RightHand,0);
                animator.SetIKRotationWeight(AvatarIKGoal.RightHand,0);
                animator.SetLookAtWeight(0);
            }
        }
    }
}

  1. 右手が Cylinder ゲームオブジェクトを通り抜けないようにするには、空の子ゲームオブジェクトを Cylinder ゲームオブジェクトに追加します。これを行うには、Hierarchy ウィンドウで Cylinder ゲームオブジェクトを右クリックし、Create Empty を選択します。この空の子ゲームオブジェクトに Cylinder Grab Handle という名前を付けます。

  2. シリンダーを通過せずに右手が触れるように、Cylinder Grab Handle ゲームオブジェクトを配置および回転します。

空のゲームオブジェクトは IK ターゲットとして機能します。この空のゲームオブジェクトを追加し、右手が Cylinder オブジェクトと正しく相互作用するようにします。

  1. Cylinder Grab Handle ゲームオブジェクトを IKControl スクリプトの Right Hand Obj プロパティとして割り当てます。
  2. Cylinder ゲームオブジェクトを Look Obj として割り当て、IK Active が有効になっているときにキャラクターがシリンダーの中心を向くようにします。

  1. 再生モードを開始します。

IK Active チェックボックスを有効/無効にすると、キャラクターはシリンダーゲームオブジェクトに触れたり離したりします。再生モードで Cylinder ゲームオブジェクトの位置と回転を変更し、右手とキャラクターの視線の反応を確認します。

ヒューマノイドアニメーションのリターゲティング
ルートモーションの仕組み