ほとんどのアニメーションは、スケルトンのジョイントを回転させ事前に決められた値に変更して作られます。子ジョイントの位置は、親の回転にもとづいて変化します。このため一連のジョイントの終了点は、角度および含まれる個々のジョイントの相対位置によって決定されます。このスケルトンのポージング手法は フォワードキネマティクス と呼ばれます。
ただし、ジョイントのポージングを行うタスクを別の視点からとらえることも、しばしば役に立ちます。例えば、空間で特定の点を決めてそこから逆算し、終了点が選択した位置になるように有効な方向にジョイントを向かせます。この方法は、選択した位置のオブジェクトをキャラクターにタッチさせたり、平らでない地面にキャラクターの足をつける、ということをする場合に役立ちます。このアプローチは インバースキネマティックス (IK )と呼ばれ、正しく設定されたアバターによる ヒューマノイドキャラクターの Mecanim でサポートされます。
キャラクターの IK を設定するには、通常は、キャラクターが相互作用するオブジェクトがシーンにあり、特に以下のような Animator 関数から IK を設定します。 SetIKPositionWeight, SetIKRotationWeight, SetIKPosition, SetIKRotation, SetLookAtPosition, bodyPosition, bodyRotation
上の画像で、キャラクターは円筒状のオブジェクトを握っています。どのようにしてこれを実現するのでしょうか。
まず、有効なアバターを持ったキャラクターを準備します。
次に、そのキャラクター用のアニメーションを少なくとも 1 つ含んだ Animator Controller を作成します。それから Animator ウィンドウの Layers ペインでレイヤー設定の歯車アイコンをクリックし、表示されたメニューの IK Pass チェックボックスをチェックします。
キャラクターの Animator コンポーネントに Animator Controller が割り当てられていることを確認してください。
次に IK を実際に処理するスクリプトをアタッチします。仮にそれを 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>();
}
// IK を計算するためのコールバック
void OnAnimatorIK()
{
if(animator) {
// IK が有効ならば、位置と回転を直接設定します
if(ikActive) {
// すでに指定されている場合は、視線のターゲット位置を設定します
if(lookObj != null) {
animator.SetLookAtWeight(1);
animator.SetLookAtPosition(lookObj.position);
}
// 指定されている場合は、右手のターゲット位置と回転を設定します
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);
}
}
//IK が有効でなければ、手と頭の位置と回転を元の位置に戻します
else {
animator.SetIKPositionWeight(AvatarIKGoal.RightHand,0);
animator.SetIKRotationWeight(AvatarIKGoal.RightHand,0);
animator.SetLookAtWeight(0);
}
}
}
}
キャラクターの手を円筒オブジェクトの内部にめりこまずに、その中心 (円筒のピボットポイント) に置くために、空の子オブジェクト (この例では Cylinder Grab Handle というオブジェクト) を配置し、手を円筒の上に置き、それに沿って回転させます。その時、手はこの子オブジェクトをターゲットにします。
ですから、この Cylinder Grab Handle ゲームオブジェクトを IKControl スクリプトの Right Hand Obj プロパティとして割り当てます。
この例では、視線のターゲットを円筒に設定します。そのため、握り手が下の方にある場合でも、キャラクターは直接オブジェクトの中心を見ます。
再生モードにすると、IK が動き出します。 Ik Active チェックボックスをクリックすると、キャラクターがオブジェクトを握ったり離したりするのを見ることができます。再生モードで円筒をいろいろ動かして、腕や手がオブジェクトに合わせて動くのを確認してみましょう。
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.