Unity5.x 动画Animator使用IK动画

Inverse Kinematics反向运动


大多数动画是由旋转关节角度的骨架来预先确定的值。孩子关节的位置变化根据父节点的旋转,因此关节链的最终位置会根据角度和它所包含的各个关节的相对位置来确定。这种方法构成的骨架被称为正运动学。

IK动画全名是Inverse Kinematics 意思是反向动力学,就是子骨骼节点带动父骨骼节点运动。比如跳街舞的少年用手撑着身体在地上转圈,手就是子骨骼,胳膊身体就是它的父骨骼,这时运动手就需要带动胳膊身体来移动。IK动画需要使用Unity5新版的动画系统中


Unity5.x 动画Animator使用IK动画_第1张图片


要设置一个IK角色,你通常有周围的场景中一个与角色交互的物体对象,然后设置IK直通脚本,特别是动画功能,如 SetIKPositionWeight, SetIKRotationWeight, SetIKPosition, SetIKRotation, SetLookAtPosition, bodyPosition, bodyRotation

在上面的例子中,我们展示了角色抓住一个圆柱形物体。我们如何做到这一点?

我们需要从一个正确配置的Avatar的人形Mecanim角色开始

接下来创建一个动画控制器,包含至少一个动画人物。然后在动画窗口的图层面板中,单击图层的齿轮设置图标,并在弹出的菜单中选中IK复选框。


Unity5.x 动画Animator使用IK动画_第2张图片

设置IK复选框默认的图层

确保动画控制器被分配给角色的动画组件: 
Unity5.x 动画Animator使用IK动画_第3张图片


接下来,附加给它一个脚本,其实需要的IK的控制,让我们叫它IKControl。该脚本设置角色的右手IK目标,并且其外观的位置,使它看起来它是持有对象:

using UnityEngine;

[RequireComponent(typeof(Animator))]
public class IKCtrl : MonoBehaviour
{
    //动画控制器
    protected Animator animator;
    //是否开启IK动画
    public bool ikActive = false;
    //右手子节点参考的目标
    public Transform rightHandObj = null;

    void Start()
    {
        //得到动画控制对象
        animator = GetComponent();
    }

    //a callback for calculating IK
    //它是回调访法。
    //前提是在Unity导航菜单栏中打开Window->Animator打开动画控制器窗口,在这里必须勾选IK Pass!!!
    void OnAnimatorIK()
    {
        if (animator)
        {

            //if the IK is active, set the position and rotation directly to the goal. 
            //即或IK动画后开始让右手节点寻找参考目标。 
            if (ikActive)
            {

                //weight = 1.0 for the right hand means position and rotation will be at the IK goal (the place the character wants to grab)
                //设置骨骼的权重,1表示完整的骨骼,如果是0.5哪么骨骼权重就是一半呢,可移动或旋转的就是一半,大家可以修改一下参数试试。
                animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1f);
                animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1f);

                //set the position and the rotation of the right hand where the external object is
                if (rightHandObj != null)
                {
                    //设置右手根据目标点而旋转移动父骨骼节点
                    animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandObj.position);
                    animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandObj.rotation);
                }

            }

            //if the IK is not active, set the position and rotation of the hand back to the original position
            //如果取消IK动画,哪么重置骨骼的坐标。
            else
            {
                animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 0);
                animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 0);
            }
        }
    }
}

由于我们不打算让角色的手到达对象的中心(圆柱体的中心点),所以我们创建一个空对象(命名为“圆柱体手柄”)放在圆柱体边缘,这样手可以在圆柱体,并相应地旋转。

Unity5.x 动画Animator使用IK动画_第4张图片

一个空的游戏对象作为IK目标,所以手会放在正确的可视圆柱体对象

在这个例子中,我们把 look target(看向目标)设置为圆柱体本身,所以最终实现角色手部触摸圆柱体下部,看向圆柱体的上部。


Unity5.x 动画Animator使用IK动画_第5张图片

进入播放模式,你应该看到IK被激活了。当您点击IKActive复选框,可以观察人物抓取和释放对象,然后尝试在播放模式移动圆柱体,可以看到胳膊和手跟随的对象。


你可能感兴趣的:(Unity)