IK 反向运动学

大多数角色动画都是通过将骨骼的关节角度旋转到预定值来实现的。一个子关节的位置是由其父关节的旋转角度决定的,这样,处于节点链末端的节点位置是由此链条上的各个节点的旋转角和相对位移来决定的。可以将这种决定骨骼位置的方法称为前向运动学。

但是,在实际应用中,上述过程的逆过程却非常实用,即给定末端节点的位置,从而逆向推出节点链上所有其他节点的合理位置。这种需求非常普遍,例如希望角色的手臂去触碰一个固定的物体或脚站立在不平坦的路面上等。这种方法被称为逆向运动学(IK),在Mecanim系统中,任何正确设置了Avatar的人形角色都支持IK功能。

为了给角色模型设置IK,需要知道可能与之进行交互的周边物体,进而设置IK脚本,常用的Animator函数包括SetIKPositionWeight()SetIKRotationWeight()SetIKPosition()SetIKRotation()SetLookAtPosition()bodyPosition()bodyRotation()

身体部位的运动

    public Transform rightHandObj; // 赋值一个用来定位右手位置的物体
    public Transform leftBowTrans; // 赋值一个用来定位左手肘部关节位置的物体

    public Transform lookTarget;

    void OnAnimatorIK() // 事件函数
    {
        // 定位头部看向目标
        animator.SetLookAtWeight(0.5f, 0.5f, 0.5f, 0.5f, 0.5f);
        animator.SetLookAtPosition(lookTarget.position);

        // 定位右手伸向目标
        animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1.0f);
        animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1.0f);

        if(rightHandObj != null)
        {
            animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandObj.position);
            animator.SetIKRotation(AvatarIKGoal.RightHand, rightHand.rotation);
        }

        // 定位左肘关节伸向目标
        animator.SetIKHintPosition(AvatarIKHint.LeftBow, leftBowTrans.position);
        animator.SetIKHintPositionWeight(AvatarIKHint.LeftBow, 1);
    }

身体的整体运动

    public void MatchTarget (Vector3 matchPosition, Quaternion matchRotation, AvatarTarget targetBodyPart, MatchTargetWeightMask weightMask, float startNormalizedTime, [DefaultValue ("1")] float targetNormalizedTime);

🔚