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.
我们所有的梦想都可以成真,只要我们有勇气去追求它们。
————沃尔特·迪斯尼