Do i need to unsubscribe my event listeners?

Hello,

myGameObject.GetUpdateEvent().AddListener(MyUpdate);

I usually work with the TypeScript Angular framework and since a few versions, it takes care of removing event listeners on destroyed components.

Does Unity require to do it manually?

Thanks

Usually yes, AFAIK if GameObject is destroyed, but you didn’t unsubscribe from event, then this event will have reference to subscribed object and GC wouldn’t be able to remove it, i.e. this will be a memory leak.
Also unsubscription makes sense in context of Unity, all of your Awake/Start/Update functions don’t work on disabled scripts or on disabled GameObjects, all unity components don’t work as well, so it makes sense to subscribe in OnEnable and unsubscribe in OnDisabled to make disabled objects purely disabled.

For plain C# events, yes, you need to manually unsubscribe.

For UnityEvents, I believe you don’t have to, and it’s taken care of automatically.
Someone correct me if I’m wrong on that.

It depends on which object you’re talking about.

Basically an event system is the observer pattern (with a different interface). So you have an observer (the thing that is listening for an event), and the subject (the thing that has an event).

When you register an event handler with the subject, the subject now has a reference to the observer (it’s a delegate, but the delegate has a reference to the observer since it’s needed to call the method in question).

This means if the observer is destroyed there is a reference still out there in the wild pointing at it which keeps the GC from cleaning it up. So when an objserver is destroyed it should unregister all event handlers. (note that static event handlers don’t matter here since there is no instanced object to reference back to).

Vice versa doesn’t actually need unregistering since the observer doesn’t actually maintain any reference to the subject (unless you explicitly did so with some variable… in which case you just need to set that variable null).

That all goes for C# events/delegates.

When it comes to UnityEvent things get a bit more complicated.

There are 2 ways to register with a UnityEvent. There are “persistent callbacks” and regular old listeners. The persistent ones are the callbacks you register through the inspector, and regular ones are done through ‘AddListener’.

AddListener approach really just is a delegate so really the rules that are applied to C# events are the same. Observer’s need to unregister themselves when destroyed otherwise the subject will hold a ref to them.

The persistent though… :shrug: on the specifics. You can sift through the source code to try and glean the specifics:

But it has all sorts of fun stuff going on in it. At first glance it appears like it would hold a reference, but there might be some unity engine side stuff that cleans it up. Could run some tests to find out… but I’m at work right now. Maybe later today when I have a longer break.

1 Like

Thanks, that’s really helpful. I havn’t dug into persistent event, i’ve only used UnityEvents so far.

Persistent callbacks are part of UnityEvent:
https://github.com/Unity-Technologies/UnityCsReference/blob/61f92bd79ae862c4465d35270f9d1d57befd1761/Runtime/Export/UnityEvent/UnityEvent.cs#L379

It’s the serializable class that facilitates registering callbacks through the inspector on a UnityEvent.

If you’ve used UnityEvent and dragged something via the inspector onto said UnityEvent… you used persistent callbacks.

I always try to subscribe and unsubscribe with OnEnable() and OnDisable() and it has never let me down.

1 Like

It is always best to unsubscribe if you’re not certain if you should. It can’t hurt.