- Home /
OnEnable not called after all Awake and not all OnDisable before OnDestroy?
The main reason I ask this is, that OnEnable and OnDisable seem to be perfect to toggle things on and off, right? Like Event-Subscriptions. Subscribe in OnEnable and Unsubscribe in OnDisable, nice. In my case, that leads to a problem, because I execute code in the add section of one of those property events. Unfortunately, the Object it's operating on is not yet referenced, because Awake on the other Object has not been called. at that time. I recognised, that I get an alternating chain of Awake and OnEnable if I debug.Log those calls.
Since the Constructor is ran by Unity, why is there not one method that runs on all GameObjects first. This way everything else would be bulletproof.
Same goes for OnDisable. I CAN'T Unsubscribe from events here, because the object I was subscribed to might not exist anymore. OnDisable and OnDestroy are also alternating their calls... How am I supposed to use toggling a script on and off with that?
Answer by darthtelle · Aug 11, 2015 at 01:16 PM
Have you checked out this Execution of Events article? Might shed some light on the actual order functions are called in the Unity lifetime. I've never seen or heard of the functions being called out of order, so you might need to rearrange some of your function calls. It's usually recommended that variables are initialised in Awake() and references set in Start(), but of course this differs for different projects and different scenarios. You might need to delay grabbing references until the thing you require is initialised. Even have the initialise function send off an event once it's up and running and THEN toggle things when receiving that event? I'm afraid I'm short of other suggestions without actually looking at your project because it sounds pretty specific!
It's actually quite in general: You can nor rely on all Awake methods being called in OnEnable, nor can you rely on all OnDisable being called before OnDestroy e.g. the actual destruction of Objects. The latter gives me errors, because on stopping the game i want to cleanly unsubscribe from events in OnDisable, which are already composted at that point. When shall I do that then???
In my specific case, I cannot use script execution order, because it would need to change during gameplay.
The order I would need it in is: - All Awake - All OnEnable - All Disable - All OnDestroy
I mean for what reason would one use OnEnable if it's for local staff on that Object only??? It's just weird
Edit: This link shows OnDisable and OnDestroy on different execution steps... not happening. OnEnable is shown after Awake along with Start, which is executed after all Awake are called which doesn't apply for OnEnabled... pretty messy if you ask me
http://docs.unity3d.com/$$anonymous$$anual/ExecutionOrder.htm
I was under the impression that all Awake(), OnEnable() etc calls are for their own object. Their own $$anonymous$$onoBehaviour. So if their object is destroyed, their OnDisable and OnDestroy is called. It doesn't work on a global scale?? I'm afraid you've confused me now with your talk of "messy", but I guess I've not had the same issues with execution order as you have.
Have you tried putting the unsubscribing in a different function? So they get called regardless of order?
private void Unsubscribe()
{
Foo.On_Event -= Bar;
}
private void OnDisable()
{
Unsubscribe();
}
private void OnDestroy()
{
Unsubscribe();
}
I meant global in sense of when happens what with ALL objects. Like the fact that the first call to Start happens after all Awake calls are done. That's a necessary thing for local and remote Object initialisation. But it seems you can't use OnEnable/-Disable that way.
And just for curiosity, how does one more level of indirection help here?
Different appoach: if you destroy a gameobject during game which was subscribed to events and that object still exists, how do you unsubscribe if you can't use OnDisable or OnDestroy, because itwellfail if you quit the game ins$$anonymous$$d of destroying the object?
I apologise for not being able to give you an answer. I was merely trying to help and was making different suggestions for you to try. I wish you the best of luck with finding a solution.