LoginSignup
13
15

More than 5 years have passed since last update.

UnityのIKで地面の形に合わせて足がつくようにした

Last updated at Posted at 2018-08-20

環境

Unity2017.3.1p4
Windows10

リポジトリ

下記リンク
Asset/Scripts/FootIK.cs
リポジトリ公開してます

How to

  1. Animatorの中からIKを有効にさせたいレイヤーの歯車をクリック
  2. 出てきたWindowのIKPassをONに
  3. Scene上にある対象のGameObjectを選択し、Animatorがアタッチされているのと同じGameObjectにFootIKをアタッチ
  4. Inspectorから地面のレイヤーネームを設定したら完了

ikpass

結果

左のUnityChanが通常状態、右がFootIKが有効状態

footik

ソース

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FootIK : MonoBehaviour {
    [SerializeField]
    private Vector3 offset = new Vector3(0,0.1f,0);
    [SerializeField]
    private float rayRange = 1f;
    [SerializeField]
    private string fieldLayerName = "Field";

    private Animator animator;

    private Transform _transform;
    public new Transform transform {
        get
        {
            if (_transform == null)
            {
                _transform = gameObject.transform;
            }
            return _transform;
        }
    }


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

    void OnAnimatorIK()
    {
        //右足
        var ray = new Ray(animator.GetIKPosition(AvatarIKGoal.RightFoot), -transform.up);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit, rayRange, LayerMask.GetMask(fieldLayerName)))
        {
            Quaternion rightRotation = Quaternion.FromToRotation(transform.up, hit.normal) * transform.rotation;
            //weightはとりあえず1で固定しておく(0f:元のアニメーション,1f:IKを完全に反映)
            animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1);
            animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1);
            animator.SetIKPosition(AvatarIKGoal.RightFoot, hit.point + offset);
            animator.SetIKRotation(AvatarIKGoal.RightFoot, rightRotation);
        }

        //左足
        ray = new Ray(animator.GetIKPosition(AvatarIKGoal.LeftFoot), -transform.up);
        if (Physics.Raycast(ray, out hit, rayRange, LayerMask.GetMask(fieldLayerName)))
        {
            Quaternion leftRotaion = Quaternion.FromToRotation(transform.up, hit.normal) * transform.rotation;

            animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1);
            animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1);
            animator.SetIKPosition(AvatarIKGoal.LeftFoot, hit.point + offset);
            animator.SetIKRotation(AvatarIKGoal.LeftFoot, leftRotaion);
        }
    }
}



もし動かない場合は

3DモデルのFBXを選択し、RigタブのConfigureをクリック

configure

Mappingが正常に行われているか確認したほうがよい
mapping

13
15
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
13
15