u3d动画系统五【StateMachineBehaviour类】
一.StateMachineBehaviour概述
状态机行为是一类特殊脚本。与将常规 Unity 脚本 (MonoBehaviour) 附加到单个游戏对象类似,您可以将 StateMachineBehaviour 脚本附加到状态机中的单个状态。因此可编写一些将在状态机进入、退出或保持在特定状态时执行的代码。这意味着您不必编写自己的逻辑来测试和检测状态的变化。
参考官方手册:状态机行为
二.StateMachineBehaviour脚本创建
如上图所示,选中状态节点,点击Add Behavior按钮创建脚本后,双击进入脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class attackState : StateMachineBehaviour
{// OnStateEnter is called when a transition starts and the state machine starts to evaluate this state//override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)//{// //}// OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks//override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)//{// //}// OnStateExit is called when a transition ends and the state machine finishes evaluating this state//override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)//{// //}// OnStateMove is called right after Animator.OnAnimatorMove()//override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)//{// // Implement code that processes and affects root motion//}// OnStateIK is called right after Animator.OnAnimatorIK()//override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)//{// // Implement code that sets up animation IK (inverse kinematics)//}
}
脚本继承StateMachineBehaviour并有五个虚方法,比较常用的是前面3个
三.案例演示
Demo说明:模型初始为idle状态,按下Q播放攻击动作,进入动作,动作进行中,动作结束时引擎会自动调用OnStateEnter,OnStateUpdate,OnStateExit
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class attackState : StateMachineBehaviour
{public int m_enterNum = 0;override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex){m_enterNum++;Debug.Log(string.Format("OnStateEnter, m_enterNum = {0}", m_enterNum));}override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex){Debug.Log("OnStateUpdate");}override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex){Debug.Log("OnStateExit");}}
事件方法参数说明:
- animator:脚本所在状态节点所在的animator组件
- AnimatorStateInfo:以get属性为主的结构体
- layerIndex:脚本所在状态节点的动画层索引
下面代码展示MonoBehaviour访问StateMachineBehaviour
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Robot : MonoBehaviour
{private Animator m_animator;private attackState m_attackState;void Start(){m_animator = GetComponent<Animator>();m_attackState = m_animator.GetBehaviour<attackState>();}void Update(){if (Input.GetKeyDown(KeyCode.Q)){m_animator.SetTrigger("attack");Debug.Log(string.Format("进入attack状态之前 m_enterNum = {0}", m_attackState.m_enterNum));}}
}