見出し画像

UnityのIKの使い方

1. IK(Inverse Kinematics)

3DCGモデルを動かすためのスケルトン構造を制御する方法の1つです。スケルトンの末端の関節(手首など)の位置と角度を設定することで、そこに至る関節(肘など)の位置と角度を自動的に計算できます。

IKを使うことで、次のようなことを実現できます。

・物を持ち上げる時の手の位置を設定。
・階段を登る時の足の位置の設定。
・坂道にあわせて、足首の向きを変える。

IKが使えるのは、アニメーション種別「Humanoid」のモデルに限られます。

Unityのモデルのアニメーション種別は、次の3種類があります。
・None: アニメーションなし。
・Generic: 人型以外(4足歩行など)のモデルのアニメーション。
・Humanoid: 人型(頭1つ、腕2つ、脚2つ)のモデルアニメーション。

2. IKを使ってみる

2つの赤い球を配置し、ニコニコ立体ちゃんに、その球を触れたままアニメーションしてもらいます。

(1) ニコニコ立体ちゃんを配置し、ユニティちゃんのAnimation「UnityChanActionCheck」を設定。
設定方法は「VRM入門」で紹介してます。

(2) 2つの赤い球を(Sphere)を配置。

◎ HandAnchorR

Position = (0.25, 1.2, 0.4)
Rotation = (0, 0, 0)
Scale = (0.06, 0.06, 0.06)

◎ HandAnchorL

Position = (-0.25, 1.2, 0.4)
Rotation = (0, 0, 0)
Scale = (0.06, 0.06, 0.06)

画像1

(3) Animation「UnityChanActionCheck」を開き、「Base Layer」の歯車マークをクリックし、「IK Pass」をチェック。
IKを利用するための準備は、これだけです。

画像2

(3) ニコニコ立体ちゃんに新規スクリプト「IKTest」を追加。

using UnityEngine;
using System.Collections;

// IKテスト
public class IKTest : MonoBehaviour {
    // 参照
    public Transform handAnchorR = null;
    public Transform handAnchorL = null;

    private Animator animator;

    // スタート時に呼ばれる
    void Start()
    {
        animator = GetComponent<Animator>();
    }

    // IK更新時に呼ばれる
    void OnAnimatorIK()
    {
        //右手
        animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1);
        animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1);
        animator.SetIKPosition(AvatarIKGoal.RightHand, handAnchorR.position);
        animator.SetIKRotation(AvatarIKGoal.RightHand, handAnchorR.rotation);

        // 左手
        animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1);
        animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1);
        animator.SetIKPosition(AvatarIKGoal.LeftHand, handAnchorL.position);
        animator.SetIKRotation(AvatarIKGoal.LeftHand, handAnchorL.rotation);
    }
}

◎ IKによる関節の位置と向きの設定
IKによる関節の位置と向きの設定は、OnAnimatorIK()内でSetIKPosition()とSetIKRotation()を使います。

void SetIKPosition(AvatarIKGoal goal, Vector3 goalPosition)
IKによる関節の位置の設定。
・goal: 設定するAvatarIKGoal
・goalPosition: ワールド空間での位置


void SetIKRotation(AvatarIKGoal goal, Quaternion goalRotation)
IKによる関節の向きの設定。
・goal: 設定するAvatarIKGoal
・goalPosition: ワールド空間での位置

「AvaterIKGoal」は、次の4種類を指定できます。

・LeftHand: 左手
・RightHand: 右手
・LeftFoot: 左足
・RightFoot: 右足

◎ IKによる関節の位置と向きの重みの設定
IKによる関節の位置と向きの重みの設定は、OnAnimatorIK()内でSetIKPositionWeight()とSetIKRotationWeight()を使います。

void SetIKPositionWeight(AvatarIKGoal goal, Vector3 goalPosition)
IKによる関節の位置の重みの設定。
・gvalue: 重み(0:IK前の元アニメーションの位置, 1:ゴール位置)


void SetIKRotation (AvatarIKGoal goal, Quaternion goalRotation)
IKによる関節の向きの重みの設定。
・gvalue: 重み(0:IK前の元アニメーションの位置, 1:ゴール位置)

IK前の元アニメーションの位置を重視する場合は0に近い値、ゴール位置を重視する場合は1に近い値を指定します。

(5) コンポーネント「IKTest」の「HandAnchorR」「HandAnchorL」に、Hierarchyウィンドウの「HandAnchorR」「HandAnchorL」をドラッグ&ドロップ。

画像3

(6) Playボタンで実行。

画像4

画像5

3. 関節のローカル回転

IKパスが有効なHumanoidのボーンは、関節のローカル回転を設定することもできます。

首を曲げでうなずくコードは、次のとおりです。

    // IK更新時に呼ばれる
   void OnAnimatorIK()
   {
       <省略>

       // 首の回転
       animator.SetBoneLocalRotation(HumanBodyBones.Head, 
           Quaternion.Euler(new Vector3(20, 0, 0)));
   }

◎ IKによる関節のローカル回転
IKによる関節のローカル回転は、OnAnimatorIK()内でSetBoneLocalRotation()を使います。

void SetBoneLocalRotation(HumanBodyBones humanBoneId, Quaternion rotation)
・humanBoneId: ボーンID
・rotation: ローカル回転

「HumanBodyBones」は、次の56種類を指定できます。

・Hips: 尻のボーン
・LeftUpperLeg: 左太もものボーン
・RightUpperLeg: 右太もものボーン
・LeftLowerLeg: 左ひざのボーン
・RightLowerLeg: 右ひざのボーン
・LeftFoot: 左足首のボーン
・RightFoot: 右足首のボーン
・Spine: 背骨の第一ボーン
・Chest: 胸のボーン
・UpperChest: 上胸のボーン
・Neck: 首のボーン
・Head: 頭のボーン
・LeftShoulder: 左肩のボーン
・RightShoulder: 右肩のボーン
・LeftUpperArm: 左上腕のボーン
・RightUpperArm: 右上腕のボーン
・LeftLowerArm: 左ひじのボーン
・RightLowerArm: 右ひじのボーン
・LeftHand: 左手首のボーン
・RightHand: 右手首のボーン
・LeftToes: 左つま先のボーン
・RightToes: 右つま先のボーン
・LeftEye: 左目のボーン
・RightEye: 右目のボーン
・Jaw: 顎のボーン

・LeftThumbProximal: 左親指第一指骨のボーン
・LeftThumbIntermediate: 左親指第二指骨のボーン
・LeftThumbDistal: 左親指第三指骨のボーン
・LeftIndexProximal: 左人差し指第一指骨のボーン
・LeftIndexIntermediate: 左人差し指第二指骨のボーン
・LeftIndexDistal: 左人差し指第三指骨のボーン
・LeftMiddleProximal: 左中指第一指骨のボーン
・LeftMiddleIntermediate: 左中指第二指骨のボーン
・LeftMiddleDistal: 左中指第三指骨のボーン
・LeftRingProximal: 左薬指第一指骨のボーン
・LeftRingIntermediate: 左薬指第二指骨のボーン
・LeftRingDistal: 左薬指第三指骨のボーン
・LeftLittleProximal: 左小指第一指骨のボーン
・LeftLittleIntermediate: 左小指第二指骨のボーン
・LeftLittleDistal: 左小指第三指骨のボーン
・RightThumbProximal: 右親指第一指骨のボーン
・RightThumbIntermediate: 右親指第二指骨のボーン
・RightThumbDistal: 右親指第三指骨のボーン
・RightIndexProximal: 右人差し指第一指骨のボーン
・RightIndexIntermediate: 右人差し指第二指骨のボーン
・RightIndexDistal: 右人差し指第三指骨のボーン
・RightMiddleProximal: 右中指第一指骨のボーン
・RightMiddleIntermediate: 右中指第二指骨
・RightMiddleDistal: 右中指第三指骨のボーン
・RightRingProximal: 右薬指第一指骨のボーン
・RightRingIntermediate: 右薬指第二指骨のボーン
・RightRingDistal: 右薬指第三指骨のボーン
・RightLittleProximal: 右小指第一指骨のボーン
・RightLittleIntermediate: 右小指第二指骨のボーン
・RightLittleDistal: 右小指第三指骨のボーン
・LastBone: 区切りになる最後のボーン


この記事が気に入ったらサポートをしてみませんか?