ヒューマノイド アニメーションのリターゲティング
メカニムにおけるジェネリック アニメーション

インバースキネマティクス (Unity Proのみ)

ほとんどのアニメーションは,スケルトンにおいて事前に決められた値にジョイントを変更して,回転することで実現されます。子ジョイントの位置は,親の回転にもとづいて変化し,このため一連のジョインの終了点は,角度および含まれる個々のジョイントの相対位置によって決定されます。このスケルトンのポージング手法は Forward Kinematics (フォワード キネマティクス)と呼ばれます。

しかし,ジョインのポージングを行うタスクを別の視点からとらえることが重要です。空間で特定の点を決めて,そこから逆算してジョイントの向きを,終了点がその位置に到着するような,有効な方法を見つけることです。オブジェクトをユーザにより選択された点をタッチさせる,または平らでない地面に足をつける,といったことをキャラクターにしてほしいときに,これは便利です。このアプローチは Inverse Kinematics (IK)と呼ばれ,メカニムで 正しく設定されたアバターのある ヒューマノイド キャラクターにおいてサポートされます。

キャラクターのIKをセットアップするためには,通常はシーンに相互作用をさせたいオブジェクトがあり,キャラクターのIKをスクリプトを通じて,具体的には次のようなAnimator関数を通じて,セットアップします。 SetIKPositionWeight, SetIKRotationWeight, SetIKPosition, SetIKRotation, SetLookAtPosition, bodyPosition, bodyRotation

上図において,キャラクターは棒の形のオブジェクトを握っています。これをどのようにして実現するのでしょうか。

まずは,有効なアバターのあるキャラクターから初めて,それにIKを処理するスクリプト IKCtrl をつけます:

using UnityEngine;
using System;
using System.Collections;
  
[RequireComponent(typeof(Animator))] 

public class IKCtrl : MonoBehaviour {
    
    protected Animator animator;
    
    public bool ikActive = false;
    public Transform rightHandObj = 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) {

                                //weight = 1.0 for the right hand means position and rotation will be at the IK goal (the place the character wants to grab)
                animator.SetIKPositionWeight(AvatarIKGoal.RightHand,1.0f);
                animator.SetIKRotationWeight(AvatarIKGoal.RightHand,1.0f);
                            
             //set the position and the rotation of the right hand where the external object is
                if(rightHandObj != null) {
                    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 back to the original position
            else {          
                animator.SetIKPositionWeight(AvatarIKGoal.RightHand,0);
                animator.SetIKRotationWeight(AvatarIKGoal.RightHand,0);             
            }
        }
    }    
}

キャラクターがオブジェクト全体を手でつかむことを意図していないため,棒のつかむ位置に球を配置し,適切に回転させます。

この球は次にIKCtrlスクリプトの“Right Hand Obj” プロパティとして配置するべきです。

IKActive チェックボックスをクリックするのにあわせて,キャラクターがオブジェクトを握って離すところを観察してください。

ヒューマノイド アニメーションのリターゲティング
メカニムにおけるジェネリック アニメーション