Unity - IK 测试

74 篇文章 5 订阅

Code

using UnityEngine;

public class MyIK : MonoBehaviour
{
    public Transform headObj = null;
    public Transform bodyObj = null;
    public Transform leftFootObj = null;
    public Transform rightFootObj = null;
    public Transform leftHandObj = null;
    public Transform rightHandObj = null;
    public Transform lookAtObj = null;

    public bool ikActive = false;

    private Animator animator;

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

    void OnAnimatorIK(int layerIndex)
    {
        if (headObj == null
            || bodyObj == null
            || leftFootObj == null 
            || rightFootObj == null 
            || leftHandObj == null 
            || rightHandObj == null 
            || lookAtObj == null)
            return;

        if (animator == null) return;

        if (ikActive)
        {
            animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1.0f);
            animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1.0f);
            animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1.0f);
            animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1.0f);
            animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1.0f);
            animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1.0f);
            animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1.0f);
            animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1.0f);
            animator.SetLookAtWeight(1.0f, 0.3f, 1.0f, 0.5f);

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

            if (leftHandObj != null)
            {
                animator.SetIKPosition(AvatarIKGoal.LeftHand, leftHandObj.position);
                animator.SetIKRotation(AvatarIKGoal.LeftHand, leftHandObj.rotation);
            }
            if (rightFootObj != null)
            {
                animator.SetIKPosition(AvatarIKGoal.RightFoot, rightFootObj.position);
                animator.SetIKRotation(AvatarIKGoal.RightFoot, rightFootObj.rotation);
            }
            if (leftFootObj != null)
            {
                animator.SetIKPosition(AvatarIKGoal.LeftFoot, leftFootObj.position);
                animator.SetIKRotation(AvatarIKGoal.LeftFoot, leftFootObj.rotation);
            }
            if (rightHandObj != null)
            {
                animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandObj.position);
                animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandObj.rotation);
            }

            if (lookAtObj != null)
            {
                animator.SetLookAtPosition(lookAtObj.position);
            }
        }
        else
        {
            if (bodyObj != null)
            {
                bodyObj.position = animator.bodyPosition;
                bodyObj.rotation = animator.bodyRotation;
            }

            if (leftFootObj != null)
            {
                leftFootObj.position = animator.GetBoneTransform(HumanBodyBones.LeftFoot).transform.position; // animator.GetIKPosition(AvatarIKGoal.LeftFoot);
                leftFootObj.rotation = animator.GetBoneTransform(HumanBodyBones.LeftFoot).transform.rotation; // animator.GetIKRotation(AvatarIKGoal.LeftFoot);
            }

            if (rightFootObj != null)
            {
                rightFootObj.position = animator.GetBoneTransform(HumanBodyBones.RightFoot).transform.position; // animator.GetIKPosition(AvatarIKGoal.RightFoot);
                rightFootObj.rotation = animator.GetBoneTransform(HumanBodyBones.RightFoot).transform.rotation; // animator.GetIKRotation(AvatarIKGoal.RightFoot);
            }

            if (leftHandObj != null)
            {
                leftHandObj.position = animator.GetBoneTransform(HumanBodyBones.LeftHand).transform.position; // animator.GetIKPosition(AvatarIKGoal.LeftHand);
                leftHandObj.rotation = animator.GetBoneTransform(HumanBodyBones.LeftHand).transform.rotation; //  animator.GetIKRotation(AvatarIKGoal.LeftHand);
            }

            if (rightHandObj != null)
            {
                rightHandObj.position = animator.GetBoneTransform(HumanBodyBones.RightHand).transform.position; // animator.GetIKPosition(AvatarIKGoal.RightHand);
                rightHandObj.rotation = animator.GetBoneTransform(HumanBodyBones.RightHand).transform.rotation; // animator.GetIKRotation(AvatarIKGoal.RightHand);
            }

            if (lookAtObj != null)
            {
                lookAtObj.position = headObj.position + headObj.forward;
            }
            animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 0);
            animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 0);
            animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 0);
            animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 0);
            animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, 0);
            animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, 0);
            animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 0);
            animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 0);
            animator.SetLookAtWeight(0.0f);
        }
    }
}

Runtime

调整:Ik Active 复选框,开启或关闭IK效果
在这里插入图片描述
以下GIF,实现刚开始是没有开启IK的,然后开启IK后,可以控制一部分IK部位信息(目标位置、旋转)
在这里插入图片描述

目前脚本中只是使用了SetIKPosition(测试foot(脚), hand(手))的测试
还有SetIKHintPosition可以测试knee(膝盖),elbow(手肘)的部位IK,这儿就不测试了,只是部位不同

References

Unity Animator动画状态机 深入理解(二)IK控制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值