1.Unity3D StateMachine正常的状态下是每个动做结束后没有回调,所以有时候我们要判断当前不是哪一个动作是要做什么的,如下:
public class TestJS : MonoBehaviour { public Animator _animator; PRivate AnimatorTransitionInfo _changeAnimator; void Update () { _changeAnimator = _animator.GetAnimatorTransitionInfo(0); if (!_changeAnimator.IsName("xxx")) { //Do Sth } }}2.这时我们就可以优化:对他们每次,进入结束弄一个回调=>状态改变: 在AnimationStateMachine里面写结束,进入的回调。
using UnityEngine;using System.Collections;using UnityEngine.Experimental.Director;public class AnimationStateMachine : StateMachineBehaviour{ public System.Action<int> EnterStateCallback; public System.Action<int> ExitStateCallback; public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { base.OnStateEnter(animator, stateInfo, layerIndex); if (EnterStateCallback != null) { EnterStateCallback(stateInfo.fullPathHash); } } public override void OnStateMachineEnter(Animator animator, int stateMachinePathHash) { base.OnStateMachineEnter(animator, stateMachinePathHash); if (EnterStateCallback != null) { EnterStateCallback(stateMachinePathHash); } } public override void OnStateMachineExit(Animator animator, int stateMachinePathHash) { base.OnStateMachineExit(animator, stateMachinePathHash); if (ExitStateCallback != null) { ExitStateCallback(stateMachinePathHash); } } public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { base.OnStateExit(animator, stateInfo, layerIndex); if (ExitStateCallback != null) { ExitStateCallback(stateInfo.fullPathHash); } }}3.这些回调还没有被初始化,此时在应用这个AnimatorControl的物体上添加脚本进行初始化:
using UnityEngine;using System.Collections;public class ParkourPlayerAnimatorController : MonoBehaviour{ //引用 private ParkourPlayerAnimationHash animHash; private int random; public Animator flyRobot; [SerializeField] private Animator playerAnimator; public ParkourAnimationStates CurrentAnimationState { get; private set; } // Use this for initialization void Awake() { random = Random.Range(0,3); animHash = GetComponent<ParkourPlayerAnimationHash>(); //最重要的在这边初始化回调函数因为结束回调暂时还可以省略,所以只是初始化进入某个动画的回调: AnimationStateMachine[] _animStateMachine = playerAnimator.GetBehaviours<AnimationStateMachine>(); for (int i = 0; i < _animStateMachine.Length; i++) { _animStateMachine[i].EnterStateCallback = SetCurrentAnimationState; } } // Update is called once per frame void Update() { } //可以保存一个CurrentAnimationState 的状态而不用像1.在Update一直判断。 void SetCurrentAnimationState(int hashName) { if (hashName == animHash.RunState) { CurrentAnimationState = ParkourAnimationStates.Run; } else if (hashName == animHash.RollState) { CurrentAnimationState = ParkourAnimationStates.Roll; } else if (hashName == animHash.JumpState || hashName == animHash.JumpState1 || hashName == animHash.JumpState2) { CurrentAnimationState = ParkourAnimationStates.Jump; } else if (hashName == animHash.MoveSideState) { CurrentAnimationState = ParkourAnimationStates.MoveSide; } else if (hashName == animHash.FallState) { CurrentAnimationState = ParkourAnimationStates.Fall; } else if (hashName == animHash.FlyTrigger) { CurrentAnimationState = ParkourAnimationStates.Fly; } } public void Run() { playerAnimator.SetBool(animHash.RunBool, true); } public void Stop() { playerAnimator.SetBool(animHash.RunBool, false); } public void PlayJump() { switch (random % 3) { case 0: playerAnimator.SetTrigger(animHash.JumpTrigger); break; case 1: playerAnimator.SetTrigger(animHash.JumpTrigger1); break; case 2: playerAnimator.SetTrigger(animHash.JumpTrigger2); break; } random++; } public void PlayRoll() { playerAnimator.SetTrigger(animHash.RollTrigger); } public void PlayMoveSideLeft() { playerAnimator.SetTrigger(animHash.MoveSideLeftTrigger); } public void PlayMoveSideRight() { playerAnimator.SetTrigger(animHash.MoveSideRightTrigger); } public void PlayFly() { playerAnimator.SetTrigger(animHash.FlyTrigger); } public void PlayFall() { playerAnimator.SetTrigger(animHash.FallTrigger); } public void PlayCatchRob() { playerAnimator.SetTrigger("Catch"); } public void PlayFlyRobot() { playerAnimator.SetTrigger(animHash.FlyTrigger); }}在3中有一个引用到animHash判断每个动画SetCurrentAnimationState(int hashName)是否相等,来记录using UnityEngine;using System.Collections;public class ParkourPlayerAnimationHash : MonoBehaviour{ public int IdleState { get; private set; } public int RunState { get; private set; } public int JumpState { get; private set; } public int JumpState1 { get; private set; } public int JumpState2 { get; private set; } public int MoveSideState { get; private set; } public int RollState { get; private set; } public int FallState { get; private set; } public int RunBool { get; private set; } public int JumpTrigger { get; private set; } public int JumpTrigger1 { get; private set;} public int JumpTrigger2 { get; private set;} public int RollTrigger { get; private set; } public int FallTrigger { get; private set; } public int FlyTrigger { get; private set; } public int MoveSideLeftTrigger { get; private set; } public int MoveSideRightTrigger { get; private set; } // Use this for initialization void Awake() { IdleState = Animator.StringToHash("Base Layer.待机"); RunState = Animator.StringToHash("Base Layer.跑步"); JumpState = Animator.StringToHash("Base Layer.跳"); JumpState1 = Animator.StringToHash("Base Layer.跳1"); JumpState2 = Animator.StringToHash("Base Layer.跳2"); MoveSideState = Animator.StringToHash("Base Layer.侧移"); RollState = Animator.StringToHash("Base Layer.下滑"); FallState = Animator.StringToHash("Base Layer.摔倒"); FlyTrigger = Animator.StringToHash("Fly"); RunBool = Animator.StringToHash("Run"); JumpTrigger = Animator.StringToHash("Jump"); JumpTrigger1 = Animator.StringToHash("Jump1"); JumpTrigger2 = Animator.StringToHash("Jump2"); RollTrigger = Animator.StringToHash("Roll"); FallTrigger = Animator.StringToHash("Fall"); MoveSideLeftTrigger = Animator.StringToHash("MoveSideLeft"); MoveSideRightTrigger = Animator.StringToHash("MoveSideRight"); }}All our dreams can come true, if we have thecourage to pursue them. 我们所有的梦想都可以成真,只要我们有勇气去追求它们。 ————沃尔特·迪斯尼
新闻热点
疑难解答