【Unity】Humanoidアニメーション内のFoot IK、Hand IKって何？どうやって使うの？

こんにちはっ🌟八ツ橋まろんです！

Unityで3Dキャラクターを使って映像を作るとき、キャラクターモーションはHumanoidアニメーションを使います。

Humanoidアニメーションは、キャラクターごとのリグの名称やTransformの違いを吸収してくれて、下の画像のように、全く別のキャラクターが同じポーズになってくれてとても便利です。

[画像：Humanoid構造なら同じ動きをしてくれる]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/cfa2df2c-b60e-2b78-01a1-98f289e907d8.png)

Humanoidアニメーションには手足や頭、腰などのリグの回転値がキーフレームとして記録されているのはわかると思いますが、実はFoot IKやHand IKのターゲットの位置も記録されています。(記録されていないものもあります)

[画像：Humanoidアニメーション内のFoot IK、Hand IKの項目]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/5fb98695-f21d-611c-f595-9f5df5540f26.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/eb70496b-17a4-f090-ba92-a2d91742110a.png)

IKというのはInverse Kinematics(インバース・キネマティクス、逆運動学)の略で、要するに『手や足首などの末端をターゲットに合わせて、肘や膝のような中間は計算で求めるよ』という動かし方です。あやつり人形を動かすような感じです。

これに対して、通常のHumanoidアニメーションはFK(フォワード・キネマティクス、順運動学)で動きます。リグを順番に回転をさせることでポーズを取らせる動かし方です。フィギュアを動かすような感じです。

Foot IKやHand IKの項目は、IKのターゲットの情報が記録されているわけですが、このIKはどうやって使うのでしょう？
(Humanoidアニメーションは通常FKモードで動作するため、Foot IKやHand IKのキーフレームは使いません。使わないならキーフレームを削除したほうがデータを軽量化できます。)

今回は、このFoot IK、Hand IKの使い方と、使うことでどうなるのかを探ってみました。

## Foot IK、Hand IKの挙動を探る

IKを使うとどんな挙動になるのかを探ってみます。(IKのオンオフの仕方は後述します)

2体の別のキャラクターを用意して、サイズを合わせます。
(Hipsボーンの高さが揃うように拡縮します)

[画像：サイズを合わせた2体、腰に刺さっているCubeはHips高さ合わせ用]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/4668f92b-0020-3492-73ab-39ee1bf3c1fe.png)

次に、2体の違いを見比べます。

UpperLegとLowerLegの開始位置にCubeを刺してみると、茶髪のキャラクターの方が少し脚が長いということがわかります。

[画像：UpperLegとLowerLegの開始位置にCubeを刺して脚の長さを比較]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/47251c0b-4916-3fdb-56c5-fd822c0396e7.png)

この状態で2体を重ねて、同じアニメーションを適用します。アニメーションは、ピンク髪のキャラクターを使って作成し書き出したものです。


[画像：同じアニメーションを適用]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/8da1268f-9297-e979-2e2f-7a560eb712e8.png)

同じポーズを取りますが、足の終着点が少し違いますね(下画像)。これは、FKモードで動作しているために、足の長いキャラクターの方が末端の移動が大きくなったためです。

[画像：茶色の靴(脚の長いキャラクター)の方が少し外側にある]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/80614716-e394-db3f-bfb7-d8851ede638a.png)


では、Foot IKを有効にしてIKモードで動作させます。
(IKモードで動作させる方法は後述)

すると、足の末端位置が同じになりました。

[画像：靴の位置が同じになった]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/87791089-19b5-7247-caae-90752b79a97d.png)

ピンク髪のキャラクターでアニメーションを作成したので、Foot IKはピンク髪のキャラクター準拠で記録されており、結果として、外側にあった脚が内側に寄りました。

つまり、Foot IKを使うことで、 **『脚の長さの違いによる足の位置ずれがなくなった』** ということになります。

これは、同じモーションのキャラクター変更や、モーションキャプチャなどで起きる『足すべり』に対して非常に有効ですが、 **想定キャラクターより脚が長いと、それだけ膝が曲がる** ことには注意してください。


次に、2体の腕の長さを比べると、茶髪のキャラクターの方が少し長いですね。

[画像：腕の長さを比較]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/530f3383-0b5a-6e72-22ec-dc45b2cc33e7.png)

先ほどのアニメーションで比べてみると、FKモードでは同じポーズですね。
ただし、腕の末端位置は腕の長いキャラクターの方が遠い位置にあります。

[画像：FKモードでの腕の比較]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/e424a8dd-4363-587d-1121-5bdb83462d73.png)

Hand IKを有効にしてみると、手の位置が同じになりました。ピンク髪のキャラクター準拠のアニメーションなので、肘を曲げることで手の位置を調整していますね。

[画像：IKモードでの腕の比較]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/eecce2b8-580a-702d-e6f4-e59097b3ba8c.png)

Hand IKを使うことで、 **『腕の長さの違いによる手の位置ずれがなくなった』** ということです。これは、 **両手を合わせたり、体をタッチするようなアニメーションでとても有効です** 。特に拍手のようなアニメーションは、キャラクターを変えると手のひらが貫通したり、隙間ができたりするので、これを吸収してくれるHand IKはとてもありがたいですね。

[画像：顔の前で手をたたくアニメーション]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/45c2b976-0611-01e6-00ab-8aafdb330cbc.png)




## Foot IKの使い方

Unityで映像制作をするときは、Timelineを使いますね。Timelineに並べたアニメーションは、アニメーション毎にFook IKの有効・無効が設定できます。

(もちろん、HumanoidアニメーションにFoot IK用のキーフレームが存在する必要がありますが)

[画像：TimelineでのFoot IKの設定箇所]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/a38f5763-7c08-a339-c89f-744454a99062.png)



## Hand IKの使い方

Foot IKと違い、Hand IKを有効にするにはスクリプトとAnimator Controllerが必要になります。Timeline機能が実装されたUnity2017以前や、そもそもTimelineを使わない場合は、Foot IKでもスクリプトとAnimator Controllerが必要です。

まずはAnimator Controllerを用意します。とはいっても準備は簡単で、新たにAnimator Controlelrを作成し、そのIK Passにチェックを入れて、キャラクターのAnimatorコンポーネントにセットするだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478685/20bf9129-73b3-0a7c-d790-c68acecb05f2.png)


そして、以下のようなスクリプトを書くことで、Hand IKが有効になり、IKモードで動作するようになります。

```CSharp:HandIK.cs
using UnityEngine;

public class HandIK : MonoBehaviour
{
    public Animator animator;

    [Range(0,1)]
    public float weight = 1;

    void OnAnimatorIK()// Animation Controller events
    {
        animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, weight);
        animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, weight);
        animator.SetIKHintPositionWeight(AvatarIKHint.LeftElbow, weight);
        animator.SetIKPositionWeight(AvatarIKGoal.RightHand, weight);
        animator.SetIKRotationWeight(AvatarIKGoal.RightHand, weight);
        animator.SetIKHintPositionWeight(AvatarIKHint.RightElbow, weight);
    }
}

```

スクリプト内のOnAnimatorIK()で、手の位置をターゲットの位置に持っていきます。
このOnAnimatorIK()はStart()やUpdate()のようにUnity側で用意されている特殊な関数で、これが発動するためにはAnimator ControllerのIK Passが有効である必要があるのです。

## まとめ

UnityのHumanoidアニメーションのFoot IK、Hand IKのキーフレームを使う方法と、その効果を探ってみました。

手足の長さが違うキャラクターに変更した際に強力な機能です。必要に応じてFKとIKで使い分けていきたいですね。

それでは🌟

八ツ橋まろん