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的退出也未可知
相关推荐
SmalBox3 天前
【节点】[Modulo节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox4 天前
【节点】[Log节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox5 天前
【节点】[Length节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox6 天前
【节点】[Exponential节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox7 天前
【节点】[Absolute节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox8 天前
【节点】[TextureSize节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox9 天前
【节点】[Texture3DAsset节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox10 天前
【节点】[Texture2DAsset节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox11 天前
【节点】[Texture2DArrayAsset节点]原理解析与实际应用
unity3d·游戏开发·图形学
SmalBox12 天前
【节点】[SplitTextureTransform节点]原理解析与实际应用
unity3d·游戏开发·图形学