如何在具有 Animator 的 GameObject 之外添加 AnimationEvent 接收器/侦听器?

Posted

技术标签:

【中文标题】如何在具有 Animator 的 GameObject 之外添加 AnimationEvent 接收器/侦听器?【英文标题】:How can I add an AnimationEvent receiver/listener outside the GameObject that has the Animator? 【发布时间】:2021-11-08 05:55:45 【问题描述】:

我有一个带有 Animator 的 GameObject 和一些可以触发事件的动画(带有特定的回调函数)。

只要我将脚本添加到与 Animator 相同的 GameObject 中,包括接收器,一切正常:

public class AnimatorEventReceiver : MonoBehaviour 
    
    void OnAnimationEnd( AnimationEvent animationEvent ) 
        // do something
    
    

(这是一个简化的例子,我去掉了任何不必要的东西)

我的问题是:我必须在包含 Animator 的 GameObject 之外侦听此事件。我可以完全访问 GameObject 本身,如何在外部添加一个“EventListener”来监听这个 AnimationEvent?

我正在寻找相当于 javascript“object.addEventListener(callback)”的 Unity/C#

应该接收 AnimationEvent 的对象是包含 Animator 的 GameObject 的父级 - 如果有帮助的话。

【问题讨论】:

【参考方案1】:

您不能直接发送,但可以通过普通事件转发,例如

public class AnimatorEventReceiver : MonoBehaviour 
   
    public event Action<AnimationEvent> OnAnimationEnded;

    void OnAnimationEnd(AnimationEvent animationEvent) 
    
        AnimationEnded?.Invoke(animationEvent);
          

然后任何其他“知道”你反对的对象都可以做,例如

public AnimatorEventReceiver eventReceiver;

private void Awake ()

    eventReceiver.OnAnimationEnded += HandleAnimationEnded;


private void OnDestroy()

    eventReceiver.OnAnimationEnded += HandleAnimationEnded;


private void HandleAnimationEnded(AnimationEvent animationEvent)

    // Do something


或者,您也可以使用 Unity 的内置 UnityEvent,这样您就可以在 Inspector 中设置回调(类似于例如 Button onClick)

// I know .. please come up with a better name :D
[Serializable]
public class AnimationEventEvent : UnityEvent<AnimationEvent>  

public class AnimatorEventReceiver : MonoBehaviour 
   
    public AnimationEventEvent OnAnimationEnded;

    void OnAnimationEnd(AnimationEvent animationEvent) 
    
        AnimationEnded.Invoke(animationEvent);
          

然后您可以在 Inspector 或任何其他“知道”您的对象可以执行的对象中添加回调,例如

public AnimatorEventReceiver eventReceiver;

private void Awake ()

    eventReceiver.OnAnimationEnded.AddListener( HandleAnimationEnded);


private void OnDestroy()

    eventReceiver.OnAnimationEnded.RemoveListener( HandleAnimationEnded);


private void HandleAnimationEnded(AnimationEvent animationEvent)

    // Do something


或者您也可以使用 Unity 的内置 UnityEvent,这样您就可以在 Inspector 中设置回调(类似于例如 Button onClick)

【讨论】:

是的,我也在考虑这个问题 - 但我认为必须有更好的方法来访问 Animator。好吧,我会给它一点时间 - 如果没有其他人有更好的方法,我会接受你的 :)

以上是关于如何在具有 Animator 的 GameObject 之外添加 AnimationEvent 接收器/侦听器?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免 Animator 动画的加速/减速?

如何从Animator中检索当前播放的动画?

Unity——Animator如何获取所有动画以及如何动态分帧播放

如何在不重复Unity动画的情况下通过Animator提高动画播放速度

animator.startAnimation -- 这个警告是啥意思?

Unity Animator只播放一次