I have a small event handler, it subscribes to many events from different objects in the Start method, and there is also an OnDestroy method where it unsubscribes from all events to which the script subscribes in the Start method.
private void Start()
{
_winPanelController.OnGiveAwards += CalculateCoins;
_revivePaymentManager.OnUpdatedBalance += SaveBalanceToJSON;
_revivePaymentManager.OnPayingFinished += RespawnAllEnemies;
_revivePaymentManager.OnPayingFinished += RevivePlayer;
_revivePaymentManager.OnPayingNotFinished += InformPlayerNotEnoughGems;
_actorUI.OnPlayerStop += SetPlayerMovement;
_wavesController.OnWin += ActivationWinPanel;
_wavesController.OnStoppedWave += StopSpawningForAllSpawners;
_wavesController.OnEnemyLevelUp += SetNewLevelForEnemies;
_player.OnDead += EnableRevivePanel;
_player.OnRevived += RespawnAllEnemies;
foreach (var spawner in _enemySpawner)
{
spawner.OnXPCollected += CalculateCollectedXP;
spawner.OnDamageCollected += CalculateCollectedDamage;
}
}
private void OnDestroy()
{
_winPanelController.OnGiveAwards -= CalculateCoins;
_revivePaymentManager.OnUpdatedBalance -= SaveBalanceToJSON;
_revivePaymentManager.OnPayingFinished -= RespawnAllEnemies;
_revivePaymentManager.OnPayingFinished -= RevivePlayer;
_revivePaymentManager.OnPayingNotFinished -= InformPlayerNotEnoughGems;
_wavesController.OnWin -= ActivationWinPanel;
_wavesController.OnStoppedWave -= StopSpawningForAllSpawners;
_wavesController.OnEnemyLevelUp -= SetNewLevelForEnemies;
_player.OnDead -= EnableRevivePanel;
_player.OnRevived -= RespawnAllEnemies;
foreach (var spawner in _enemySpawner)
{
spawner.OnXPCollected -= CalculateCollectedXP;
spawner.OnDamageCollected -= CalculateCollectedDamage;
}
}`
The question is that I don't understand where I can track how many events I have subscribed to, how much RAM or CPU time they take? Or is it not possible to track this? And what happens if I don't unsubscribe from these events, how can I track the memory leak?
I tried to find something related to events in Memory Profiler, but I didn't find anything either. The most I found in the Profiler is the process Update.ScriptsRunBehaviorUpdate > BehaviorUpdate > EventSystem.Update() [Invoke]. Is this the standard EventSystem from Unity?
You can look into the answers of this question. There are options for doing it with an attached debugger and via reflection. I'd never advise you to use reflection on a shipping build, though. If it's just for you and debugging purposes, it's fine, but it comes with an overhead and may not be available on all platforms.
Very little. They hold a reference to the object and a function pointer in an internal list. Even if you have hundreds of subscribers, you won't notice an impact, really. It's basically a loop that iterates over all the functions to invoke them on their objects and pass the parameters.
See my point about debugging them, above. You can totally look into what's going on internally, but if you really want to track it, you should probably run an internal event system, but that can get messy as well.
That's a really good question. Usually, when an object goes out of scope and is garbage collected, the events don't care about it and it will be removed from the invocation list. In Unity when you subscribe with a Unity managed object (something that inherits from
MonoBehaviourorScriptableObject), they will not be removed from the invocation list and the events will be called on them. I advise to unsubscribe them and if you ever have some weird NullReferenceException on an object that shouldn't be there, make sure that you have unsubscribed from all events like you described.