如何在具有动画器的游戏对象之外添加动画事件接收器/侦听器?

Kat*_*tai 2 c# animation event-handling unity-game-engine

我有一个带有动画器的游戏对象和一些可以触发事件的动画(具有特定的回调函数)。

在此输入图像描述

只要我将脚本添加到与动画器相同的游戏对象(包括接收器),一切都会正常工作:

在此输入图像描述

public class AnimatorEventReceiver : MonoBehaviour {
    
    void OnAnimationEnd( AnimationEvent animationEvent ) {
        // do something
    }
    
}
Run Code Online (Sandbox Code Playgroud)

(这是一个简化的例子,我删除了所有不必要的东西)

我的问题是:我必须在包含动画器的游戏对象之外监听此事件。我可以完全访问 GameObject 本身,如何在外部添加“EventListener”来侦听此 AnimationEvent?

我正在寻找 Javascript“object.addEventListener(callback)”的 Unity/C# 等效项

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

der*_*ugo 5

您不能直接但您可以通过正常事件转发它,例如

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

    void OnAnimationEnd(AnimationEvent animationEvent) 
    {
        AnimationEnded?.Invoke(animationEvent);
    }      
}
Run Code Online (Sandbox Code Playgroud)

然后“知道”您对象的任何其他对象都可以执行以下操作,例如

public AnimatorEventReceiver eventReceiver;

private void Awake ()
{
    eventReceiver.OnAnimationEnded += HandleAnimationEnded;
}

private void OnDestroy()
{
    eventReceiver.OnAnimationEnded += HandleAnimationEnded;
}

private void HandleAnimationEnded(AnimationEvent animationEvent)
{
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

或者,您也可以使用 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);
    }      
}
Run Code Online (Sandbox Code Playgroud)

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

public AnimatorEventReceiver eventReceiver;

private void Awake ()
{
    eventReceiver.OnAnimationEnded.AddListener( HandleAnimationEnded);
}

private void OnDestroy()
{
    eventReceiver.OnAnimationEnded.RemoveListener( HandleAnimationEnded);
}

private void HandleAnimationEnded(AnimationEvent animationEvent)
{
    // Do something
}
Run Code Online (Sandbox Code Playgroud)