LoginSignup
12
9

More than 3 years have passed since last update.

Unity 手書きでさくっとIK (Inverse Kinematics)

Posted at

UnityでHumanoid(人型)モデルにポーズをつけたい

最初はanimationファイルの中で各関節の曲がり具合を手動で編集してました
めちゃくちゃ大変
Very Animationなど使いやすいソフトもありますが、それでも大変

image.png
パラメータ多い…

なぜ大変なのか

3Dモデルのアニメーションは各関節の位置や曲がり具合で定義します

しかし、例えばコップを取る動作、私たちは「手をコップの位置に持ってくる」ということしか意識していません
右ひじを45度曲げて、肩を10度下げて・・・などと日常考えているわけではありません

それを3Dモデルでいきなりやろうとしても、非常に難しい

そこでIK

逆に目標物の位置や向きから各関節の位置や曲がり具合を計算することもできます
IK(= inverse kinematics)といいます
普通にその方がいいよね?

やり方

  • Unityに適当なHumanoidモデルをインポート、Scene上に設置
    • Import SettingsでRig->Animation TypeがHumanoidなことを確認
  • Unityに以下スクリプトをインポート
IKTest.cs
using UnityEngine;
using System.Collections;

public class IKTest : MonoBehaviour {

  public Transform lookAtObject = null;
  public Transform handR = null;
  public Transform handL = null;
  public Transform waist = null;
  public Transform footR = null;
  public Transform footL = null;

  private Animator animator;

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

  void OnAnimatorIK()
  {
    if (lookAtObject != null) {
      animator.SetLookAtWeight(1.0f, 0.8f, 1.0f, 0.0f, 0f);
      animator.SetLookAtPosition(lookAtObject.position);
    }

    if (handR != null) {
      animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1);
      animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1);
      animator.SetIKPosition(AvatarIKGoal.RightHand, handR.position);
      animator.SetIKRotation(AvatarIKGoal.RightHand, handR.rotation);
    }

    if (handL != null) {
      animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1);
      animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1);
      animator.SetIKPosition(AvatarIKGoal.LeftHand, handL.position);
      animator.SetIKRotation(AvatarIKGoal.LeftHand, handL.rotation);
    }

    if (waist != null) {
      animator.bodyPosition = waist.position;
      animator.bodyRotation = waist.rotation;
    }

    if (footR != null) {
      animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1);
      animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1);
      animator.SetIKPosition(AvatarIKGoal.RightFoot, footR.position);
      animator.SetIKRotation(AvatarIKGoal.RightFoot, footR.rotation);
    }

    if (footL != null) {
      animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1);
      animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1);
      animator.SetIKPosition(AvatarIKGoal.LeftFoot, footL.position);
      animator.SetIKRotation(AvatarIKGoal.LeftFoot, footL.rotation);
    }
  }
}

  • このスクリプトをHumanoidモデルにドラッグしてコンポーネントとしてアタッチ
  • 手足・腰・見てる物の5つの目印となるオブジェクトを作成(SphereでもCubeでも)
  • 先ほどのコンポーネントにそれぞれドラッグしてアタッチ

image.png

  • Game再生

IKTest.gif

できた!

参考

公式のドキュメント: IK

12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9