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的退出也未可知
相关推荐
SmalBox7 小时前
03-06-架构篇-资源依赖与分组架构
unity3d·游戏开发
鑫鑫哥adam11 小时前
一局游戏的时长,凭什么信客户端说的?
unity3d·游戏开发
Behavior19 小时前
国内下载使用 Unity 6000 踩坑点总结
c#·unity3d·游戏开发
SmalBox2 天前
03-05-架构篇-操作异步体系(OperationSystem)
unity3d·游戏开发
SmalBox3 天前
03-04-架构篇-文件系统架构(IFileSystem)
unity3d·游戏开发
鑫鑫哥adam13 天前
一个 1x1 贴图,是怎么炸掉整个热更包的?
unity3d·游戏开发
Behavior14 天前
Unity 手游动态更换 App 图标 — Android 与 iOS 双端技术方案
c#·unity3d·游戏开发
SmalBox14 天前
03-03-架构篇-Runtime加载系统架构
unity3d·游戏开发
SmalBox14 天前
03-02-架构篇-Editor打包系统架构
unity3d·游戏开发
Behavior14 天前
Unity 手游 iOS Deep Link 唤醒全流程:从 URL Scheme / Universal Links 到 C# 层参数投递
c#·unity3d·游戏开发