关于“官方案例精选”一书中Mecanim章节中的IK小结部分的无法再5.x以上版本正确触发

  • 概述:

笔者在“官方案例精选”一书中,第六章的Mecanim中的IK讲解的部分,遇到部分疑惑的地方;接下来,为可能有与我相同问题的伙伴,说明下我测试的结果。

  • 提出问题:

  1. 匹配Effector位置的脚本,放置在Update函数中无法正确的找到位置的问题(书中是指明还在Update函数,但是其实demo里面的IK脚本,并没有把匹配位置的函数,放置在Update中);而是放置在回调函数OnAnimatorIK(int layerIndex)中

  • 解决办法:

不要按照书中所描述的,放置脚本在Update中;而是将这部分代码,放置在回调函数OnAnimatorIK(int layerIndex)中

  • 测试过程:
  1. 首先将官方的demo脚本,放置在Update中,也是无法正确触发的情况;
  2. 放置在回调函数OnAnimatorIK(int layerIndex)中,正确操作
代码部分:
  1. 错误方式:
 /// <summary>
/// 
/// </summary>

using UnityEngine;
using System;
using System.Collections;
  
[RequireComponent(typeof(Animator))]  

//Name of class must be name of file as well

public class IK : MonoBehaviour {
	
	protected Animator avatar;
	
	public bool ikActive = false;
	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 float leftFootWeightPosition = 1;
	public float leftFootWeightRotation = 1;

	public float rightFootWeightPosition = 1;
	public float rightFootWeightRotation = 1;
	
	public float leftHandWeightPosition = 1;
	public float leftHandWeightRotation = 1;
	
	public float rightHandWeightPosition = 1;
	public float rightHandWeightRotation = 1;

	public float lookAtWeight = 1.0f;
	
	// Use this for initialization
	void Start () 
	{
		avatar = GetComponent<Animator>();
	}

	void OnGUI()
	{

		GUILayout.Label("Activate IK and move the Effectors around in Scene View");
		ikActive = GUILayout.Toggle(ikActive, "Activate IK");
	}

    void Update()
    {
        //不应该把下部分代码,放置在Update中
        if (!ikActive)
        {
            avatar.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 0);
            avatar.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 0);

            avatar.SetIKPositionWeight(AvatarIKGoal.RightFoot, 0);
            avatar.SetIKRotationWeight(AvatarIKGoal.RightFoot, 0);

            avatar.SetIKPositionWeight(AvatarIKGoal.LeftHand, 0);
            avatar.SetIKRotationWeight(AvatarIKGoal.LeftHand, 0);

            avatar.SetIKPositionWeight(AvatarIKGoal.RightHand, 0);
            avatar.SetIKRotationWeight(AvatarIKGoal.RightHand, 0);

            avatar.SetLookAtWeight(0.0f);

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

            if (leftFootObj != null)
            {
                leftFootObj.position = avatar.GetIKPosition(AvatarIKGoal.LeftFoot);
                leftFootObj.rotation = avatar.GetIKRotation(AvatarIKGoal.LeftFoot);
            }

            if (rightFootObj != null)
            {
                rightFootObj.position = avatar.GetIKPosition(AvatarIKGoal.RightFoot);
                rightFootObj.rotation = avatar.GetIKRotation(AvatarIKGoal.RightFoot);
            }

            if (leftHandObj != null)
            {
                leftHandObj.position = avatar.GetIKPosition(AvatarIKGoal.LeftHand);
                leftHandObj.rotation = avatar.GetIKRotation(AvatarIKGoal.LeftHand);
            }

            if (rightHandObj != null)
            {
                rightHandObj.position = avatar.GetIKPosition(AvatarIKGoal.RightHand);
                rightHandObj.rotation = avatar.GetIKRotation(AvatarIKGoal.RightHand);
            }


            if (lookAtObj != null)
            {
                lookAtObj.position = avatar.bodyPosition + avatar.bodyRotation * new Vector3(0, 0.5f, 1);
            }
        }
    }
		
    
	void OnAnimatorIK(int layerIndex)
	{		
		if(avatar)
		{
			if(ikActive)
			{
				avatar.SetIKPositionWeight(AvatarIKGoal.LeftFoot,leftFootWeightPosition);
				avatar.SetIKRotationWeight(AvatarIKGoal.LeftFoot,leftFootWeightRotation);
							
				avatar.SetIKPositionWeight(AvatarIKGoal.RightFoot,rightFootWeightPosition);
				avatar.SetIKRotationWeight(AvatarIKGoal.RightFoot,rightFootWeightRotation);
	
				avatar.SetIKPositionWeight(AvatarIKGoal.LeftHand,leftHandWeightPosition);
				avatar.SetIKRotationWeight(AvatarIKGoal.LeftHand,leftHandWeightRotation);
							
				avatar.SetIKPositionWeight(AvatarIKGoal.RightHand,rightHandWeightPosition);
				avatar.SetIKRotationWeight(AvatarIKGoal.RightHand,rightHandWeightRotation);
				
				avatar.SetLookAtWeight(lookAtWeight,0.3f,0.6f,1.0f,0.5f);
				
				if(bodyObj != null)
				{
					avatar.bodyPosition = bodyObj.position;
					avatar.bodyRotation = bodyObj.rotation;
				}				

				if(leftFootObj != null)
				{
					avatar.SetIKPosition(AvatarIKGoal.LeftFoot,leftFootObj.position);
					avatar.SetIKRotation(AvatarIKGoal.LeftFoot,leftFootObj.rotation);
				}				
			
				if(rightFootObj != null)
				{
					avatar.SetIKPosition(AvatarIKGoal.RightFoot,rightFootObj.position);
					avatar.SetIKRotation(AvatarIKGoal.RightFoot,rightFootObj.rotation);
				}				

				if(leftHandObj != null)
				{
					avatar.SetIKPosition(AvatarIKGoal.LeftHand,leftHandObj.position);
					avatar.SetIKRotation(AvatarIKGoal.LeftHand,leftHandObj.rotation);
				}				
			
				if(rightHandObj != null)
				{
					avatar.SetIKPosition(AvatarIKGoal.RightHand,rightHandObj.position);
					avatar.SetIKRotation(AvatarIKGoal.RightHand,rightHandObj.rotation);
				}				
				
				if(lookAtObj != null)
				{
					avatar.SetLookAtPosition(lookAtObj.position);
				}				
			}
			else
			{
				
			}
		}
	}  
}

2. 正确方式:

using UnityEngine;

public class ConfigIK : MonoBehaviour
{

    public Transform bodyObj;
    public Transform headObj;
    public Transform lefthandObj;
    public Transform righthandObj;
    public Transform leftfootObj;
    public Transform rightfootObj;

    private Animator avatar;
    private bool isActive = false;


    void Start()
    {
        avatar = GetComponent<Animator>();



    }


    void Update()
    {


    }

    void OnAnimatorIK(int layerIndex)
    {
        if (isActive)
        {
            avatar.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1);
            avatar.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1);
            avatar.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1);
            avatar.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1);
            avatar.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1);
            avatar.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1);
            avatar.SetIKPositionWeight(AvatarIKGoal.RightHand, 1);
            avatar.SetIKRotationWeight(AvatarIKGoal.RightHand, 1);
            avatar.SetLookAtWeight(1.0f, 0.8f);

            if (leftfootObj != null)
            {
                avatar.SetIKPosition(AvatarIKGoal.LeftFoot, leftfootObj.position);
                avatar.SetIKRotation(AvatarIKGoal.LeftFoot, leftfootObj.rotation);
            }
            if (rightfootObj != null)
            {
                avatar.SetIKPosition(AvatarIKGoal.RightFoot, rightfootObj.position);
                avatar.SetIKRotation(AvatarIKGoal.RightFoot, rightfootObj.rotation);
            }
            if (lefthandObj != null)
            {
                avatar.SetIKPosition(AvatarIKGoal.LeftHand, lefthandObj.position);
                avatar.SetIKRotation(AvatarIKGoal.LeftHand, lefthandObj.rotation);
            }
            if (righthandObj != null)
            {
                avatar.SetIKPosition(AvatarIKGoal.RightHand, righthandObj.position);
                avatar.SetIKRotation(AvatarIKGoal.RightHand, righthandObj.rotation);
            }
            if (headObj != null)
            {
                avatar.SetLookAtPosition(headObj.position);
            }
            if (bodyObj != null)
            {
                avatar.bodyPosition = bodyObj.position;
                avatar.bodyRotation = bodyObj.rotation;
            }
        }
        else
        {

            avatar.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 0);
            avatar.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 0);
            avatar.SetIKPositionWeight(AvatarIKGoal.RightFoot, 0);
            avatar.SetIKRotationWeight(AvatarIKGoal.RightFoot, 0);
            avatar.SetIKPositionWeight(AvatarIKGoal.LeftHand, 0);
            avatar.SetIKRotationWeight(AvatarIKGoal.LeftHand, 0);
            avatar.SetIKPositionWeight(AvatarIKGoal.RightHand, 0);
            avatar.SetIKRotationWeight(AvatarIKGoal.RightHand, 0);
            avatar.SetLookAtWeight(0f);

            if (bodyObj != null)
            {
                bodyObj.position = avatar.bodyPosition;
                bodyObj.rotation = avatar.bodyRotation;
            }
            if (lefthandObj != null)
            {
                lefthandObj.position = avatar.GetIKPosition(AvatarIKGoal.LeftHand);
                lefthandObj.rotation = avatar.GetIKRotation(AvatarIKGoal.LeftHand);
            }
            if (righthandObj != null)
            {
                righthandObj.position = avatar.GetIKPosition(AvatarIKGoal.RightHand);
                righthandObj.rotation = avatar.GetIKRotation(AvatarIKGoal.RightHand);
            }
            if (leftfootObj != null)
            {
                leftfootObj.position = avatar.GetIKPosition(AvatarIKGoal.LeftFoot);
                leftfootObj.rotation = avatar.GetIKRotation(AvatarIKGoal.LeftFoot);
            }
            if (rightfootObj != null)
            {
                rightfootObj.position = avatar.GetIKPosition(AvatarIKGoal.RightFoot);
                rightfootObj.rotation = avatar.GetIKRotation(AvatarIKGoal.RightFoot);
            }
            if (headObj != null)
                headObj.position = avatar.bodyPosition + avatar.bodyRotation * new Vector3(0, 0.5f, 1.0f);

        }
    }

    void OnGUI()
    {
        isActive = GUILayout.Toggle(isActive, "isActive");
    }
}

  • 总结:

笔者使用的Unity是5.3.6版本·

(我记得在最初学这个的时候,并没有想到此问题,估计是unity版本高了的问题存在)

猜你喜欢

转载自blog.csdn.net/CSDN1023729504/article/details/80077493