Home > front end >  How can I add an AnimationEvent receiver/listener outside the GameObject that has the Animator?
How can I add an AnimationEvent receiver/listener outside the GameObject that has the Animator?

Time:09-17

I have a GameObject with an Animator and some animations that can trigger an event (with a specific callback function).

enter image description here

As long as I add a Script to the same GameObject as the Animator, that includes the receiver, everything works fine:

enter image description here

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

(it's a simplified example, I stripped anything unecessary)

My problem is: I have to listen for this event outside of the GameObject that contains the Animator. I have full access to the GameObject itself, how can I externally add an "EventListener" to listen for this AnimationEvent?

I'm kind of looking for the Unity/C# equivalent of a Javascript "object.addEventListener( callback )"

The object that should receive the AnimationEvent, is the parent of the GameObject containing the Animator - if that helps.

CodePudding user response:

You can't directly but you could forward it via a normal event like e.g.

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

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

Then any other object that "knows" you object can do e.g.

public AnimatorEventReceiver eventReceiver;

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

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

private void HandleAnimationEnded(AnimationEvent animationEvent)
{
    // Do something
}

Or alternatively you could also use Unity's built-in UnityEvent so you can setup callbacks already in the Inspector (similar to e.g. 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);
    }      
}

Then you can either add callbacks in the Inspector or any other object that "knows" you object can do e.g.

public AnimatorEventReceiver eventReceiver;

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

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

private void HandleAnimationEnded(AnimationEvent animationEvent)
{
    // Do something
}

Or alternatively you could also use Unity's built-in UnityEvent so you can setup callbacks already in the Inspector (similar to e.g. Button onClick)

  • Related