Unity —— Animator 状态机事件通知(Animator 1-2)

一. 状态机监听

  1. AnimStateHook - 状态机钩子
  • 继承自 Unity 的 StateMachineBehaviour,附加到 Animator Controller 的状态上
  • 拦截 Animator 的三个生命周期回调:OnAnimEnter、OnAnimUpdate、OnAnimExit
  • 从 Animator 所在 GameObject 获取 AnimEventDispatcher 组件并转发事件
csharp 复制代码
public class AnimStateHook : StateMachineBehaviour
{
    public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex, AnimatorControllerPlayable controller)
    {
        AnimEventDispatcher call = animator.gameObject.GetComponent<AnimEventDispatcher>();
        if (call != null)
        {
            call.OnEnterChannel(animator, stateInfo, layerIndex);
        }
    }

    public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex, AnimatorControllerPlayable controller)
    {
        AnimEventDispatcher call = animator.gameObject.GetComponent<AnimEventDispatcher>();
        if (call != null)
        {
            call.OnUpdateChannel(animator, stateInfo, layerIndex);
        }
    }

    public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex, AnimatorControllerPlayable controller)
    {
        AnimEventDispatcher call = animator.gameObject.GetComponent<AnimEventDispatcher>();
        if (call != null)
        {
            call.OnExitChannel(animator, stateInfo, layerIndex);
        }
    }
}
  1. AnimEventDispatcher - 事件分发器
  • 作为 MonoBehaviour 组件挂载在有 Animator 的 GameObject 上, 提供外部监听方法
  • 接收 AnimStateHook 的回调并广播对应事件
arduino 复制代码
public class AnimEventDispatcher : MonoBehaviour
{
    public Action<int, float> OnEnterEvent;
    public Action<int, float> OnUpdateEvent;
    public Action<int, float> OnExitEvent;


    public void OnEnterChannel(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        OnEnterEvent?.Invoke(stateInfo.shortNameHash, stateInfo.normalizedTime);
    }

    public void OnUpdateChannel(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        OnUpdateEvent?.Invoke(stateInfo.shortNameHash, stateInfo.normalizedTime);
    }

    public void OnExitChannel(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        OnExitEvent?.Invoke(stateInfo.shortNameHash, stateInfo.normalizedTime);
    }
}

  1. 总结: 如上提供了一种监听Animator状态变化的监听方法, 入状态进入(Enter), 状态Update(Update), 状态退出(Exit)注意事项
  • normalizedTime为百分比时间
  • 两个相邻状态A -> B, Unity无法保证A的退出先执行, B的进入后执行, 可能先执行B的进入,再执行A的退出也未可知
相关推荐
有中二病没中二命3 小时前
Unity —— 图集参数 & 自动图集生成
unity3d
SmalBox1 天前
【节点】[GatherTexture2DNode节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox2 天前
【节点】[CubemapAsset节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox3 天前
【节点】[CalculateLevelOfDetailTexture2DNode节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox4 天前
【节点】[Screen节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox5 天前
【节点】[SceneDepthDifference节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox6 天前
【节点】[SceneDepth节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox7 天前
【节点】[SceneColor节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox8 天前
【节点】[Object节点]原理解析与实际应用
unity3d·游戏开发·图形学