關於“官方案例精選”一書中Mecanim章節中的IK小結部分的無法再5.x以上版本正確觸發
阿新 • • 發佈:2019-02-14
- 概述:
筆者在“官方案例精選”一書中,第六章的Mecanim中的IK講解的部分,遇到部分疑惑的地方;接下來,為可能有與我相同問題的夥伴,說明下我測試的結果。
- 提出問題:
- 匹配Effector位置的指令碼,放置在Update函式中無法正確的找到位置的問題(書中是指明還在Update函式,但是其實demo裡面的IK指令碼,並沒有把匹配位置的函式,放置在Update中);而是放置在回撥函式OnAnimatorIK(int layerIndex)中
- 解決辦法:
不要按照書中所描述的,放置指令碼在Update中;而是將這部分程式碼,放置在回撥函式OnAnimatorIK(int layerIndex)中
- 測試過程:
- 首先將官方的demo指令碼,放置在Update中,也是無法正確觸發的情況;
- 放置在回撥函式OnAnimatorIK(int layerIndex)中,正確操作
- 錯誤方式:
/// <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版本高了的問題存在)