Unity中如何在挂载Animator的GameObject外部添加AnimationEvent监听器
实现方案
Unity的AnimationEvent默认只能触发挂载Animator的GameObject上挂载的脚本的对应方法,要实现外部监听,只要加一层事件转发即可,具体步骤如下:
1. 改造动画事件接收脚本
给原来的接收脚本加一个公开的委托事件,收到AnimationEvent的时候直接转发出去:
public class AnimatorEventReceiver : MonoBehaviour { // 定义委托类型,参数和动画事件的回调一致 public delegate void AnimationEndHandler(AnimationEvent animationEvent); // 公开的可订阅事件 public event AnimationEndHandler OnAnimationEndEvent; // 动画事件触发的原生接收方法 void OnAnimationEnd(AnimationEvent animationEvent) { // 事件不为空就广播给所有订阅者 OnAnimationEndEvent?.Invoke(animationEvent); } }
2. 父物体脚本订阅事件
接收方是Animator所在物体的父物体,直接在父物体的脚本里获取子物体上的AnimatorEventReceiver组件,订阅对应的事件即可,写法和JS的addEventListener逻辑完全一致:
public class ParentObjectScript : MonoBehaviour { void Start() { // 获取子物体上的事件转发组件,也可以直接在Inspector赋值更稳妥 AnimatorEventReceiver eventReceiver = GetComponentInChildren<AnimatorEventReceiver>(); // 订阅事件,和JS的addEventListener效果相同 eventReceiver.OnAnimationEndEvent += HandleAnimationEnd; } // 收到动画事件后的处理逻辑 private void HandleAnimationEnd(AnimationEvent animationEvent) { // 在这里写你的业务逻辑 Debug.Log("父物体收到动画结束事件:" + animationEvent.animatorClipInfo.clip.name); } // 物体销毁时取消订阅,避免内存泄漏 void OnDestroy() { AnimatorEventReceiver eventReceiver = GetComponentInChildren<AnimatorEventReceiver>(); if (eventReceiver != null) { eventReceiver.OnAnimationEndEvent -= HandleAnimationEnd; } } }
拓展说明
如果需要监听多个不同名称的动画事件,只需要在AnimatorEventReceiver里对应添加多个事件和对应的原生接收方法即可。
内容的提问来源于stack exchange,提问作者Katai
相关产品推荐
相关产品推荐

