Search Unity

Execution Order of Events for scripts with ExecutInEditMode attribute

Discussion in 'Documentation' started by Xarbrough, Nov 7, 2016.

  1. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    I couldn't find the documentation about when and in which order Awake, OnEnable and Start are called in the editor, when using the ExecuteInEditMode attribute on a MonoBehaviour.

    The docs currently only mention Update, OnGUI and OnRenderObject. The other callbacks do work and I can observe, that all three are called, when a script is added to a GameObject and OnEnable is called after script reload when recompiling, but it would be more assuring to see the official rules.

    Thanks!
     
  2. Graham-Dunnett

    Graham-Dunnett

    Administrator

    Joined:
    Jun 2, 2009
    Posts:
    4,287
  3. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    Thanks for your reply! The linked page is missing clarification about which callbacks happen and when they occur if using the ExecuteInEditMode callback in edit mode.

    Especially interesting:
    1. When is Awake called? Only when a script is created in the editor or also when I open the scene or on recompile?
    2. When is Start called? Also a few different occasions when this can be called, but appears to be the same as Awake.
    3. OnEnable? Seems to be called after recompile, but also after assembly reload.
     
  4. Graham-Dunnett

    Graham-Dunnett

    Administrator

    Joined:
    Jun 2, 2009
    Posts:
    4,287
    I'll get some homework done. Very reasonable questions. Someone here will be an expert. :)
     
    Xarbrough likes this.
  5. StephenHodgson-Valorem

    StephenHodgson-Valorem

    Joined:
    Mar 8, 2017
    Posts:
    148
    OnApplicationFocus is also missing, and is only called in the editor.
     
  6. Bezzy

    Bezzy

    Joined:
    Apr 1, 2009
    Posts:
    75
    Hi there. I ran this area of confusion and wanted to just make a post to make clear what's happening with respect to Multi Scene Editing, Scene Loading, and function execution order.

    When a scene is loaded, their Awake and OnEnable are called. First all the Awake()s, then all the OnEnable()s. This, you probably already know.

    But, note that, that if you are in multi scene edit, it ISN'T as if you've added all the loaded scenes' contents to a mega-scene. Instead, you should think of the HierachyView as performing a bit of a macro to load the list of open scenes in order.
    i.e. When you hit Play:
    • Load SceneA
      • Execute All Awake()s in this scene
      • Execute All OnEnable()s (if component enabled) in this scene
    • Load SceneB
      • Execute All Awake()s in this scene
      • Execute All OnEnable()s (if component enabled) in this scene

    So, you have to respect the load order of the Scenes themselves. i.e you cannot assume that something set in an Awake() in SceneB is ready for use by an OnEnable() in SceneA. You must be aware of the order they are loaded.

    The other thing I noticed while debugging was that, if you have [ExecuteInEditMode], when you hit play, you'll get an "unload" call on that script, before the true loading occurs.

    I realize this seems really obvious in hindsight, but where there's stuff like [ExecuteInEditMode] which causes OnDisable() and OnDestroy() to be called, and also ExecutionOrder seems to be the go-to fix for making singletons exist before the code that uses them, it really muddies the waters, so I just thought I'd write up some clarification.
     
    Last edited: Dec 6, 2017
  7. Glurth

    Glurth

    Joined:
    Dec 29, 2014
    Posts:
    109
    I'm also having some unexpected results with ExecuteInEditMode:
    Tests show that when I create (in a MenuItem function) a GameObject then add my component to it... my component's OnEnable(), is called BEFORE Reset()
    I want Reset() to set up my component's members upon creation, but OnEnable (which expects stuff to be setup) is actually running first. I don't want to use Awake() because I only want the reset action to occur upon creation or manual Reset, NOT whenever the component is loaded.

    According to the manual page @Graham-Dunnett mentioned, Reset() is supposed to be called before anything else.

    What am I missing here?
     
  8. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    938
    I am reviving this thread since I am also running into confusion about the exact execution orders of these events when implementing a script with the ExecuteInEditMode or ExecuteAlways attributes.

    Was there any action taken for this at all? I cannot for the life of me find any reasonable documentation about these event execution orders when using above mentioned attributes in the docs.

    There is only this manual page which was already mentioned, but does not actually cover any significant editmode scenario's on execution order and especially when talking about the same event types between two different scripts (for example, when is OnEnable of MonobehaviourA vs MonobehaviourB called). This leads me to having to Debug.Log every event call of every script in order to find out what is going on.

    At the same time there is the struggle to get script serialization right with Unity's half-functional serialization restrictions, leaving you with suddenly-null or re-initialized variables. And I am not even using a single static variable here, just the component scripts itself.

    Then there is also new functionality which allows you to disable domain reloads and scene reloads, which changes the execution order all over again.

    Combine that with bugs like these where script do not even adhere to your defined execution order and you are left with one big goopy mess, of which no one has any clue what is going on, or what the best practice is to make your script work correctly with edit mode.

    I would like to see a manual page which clearly describes the best practices of which functions to use for certain initializations, setting up references to other objects or components etc. The documentation on this aspect is severaly lacking and most information I could find about this was hidden in forum posts and bug reports all over the place.

    How is it that there is not a single dedicated documentation page about what events to use for which purpose? There should be a clear guideline about this such that, whatever the playmode reload settings or script execution orders, this always works reliably and as expected? Like: Use Awake to setup local and private variables in your script, use OnEnable and Start to setup references to other scripts or objects using GetComponent? I am still not even sure what goes where when using ExecuteInEditMode since I often encounter a situation where one script's variables are suddenly null because the respective events are suddenly executed in a different order.

    Please outline the details about this on a documentation page somewhere!
     
    LazloBonin and Glurth like this.
  9. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    812
    +1. Hard agree. Order of execution of events, both in play and edit mode, is the very core of any architecture in Unity. This needs to be explicitly documented. @Graham-Dunnett, are you aware of any update to this?
     
    Vanamerax likes this.
  10. jamesb-unity

    jamesb-unity

    Unity Technologies

    Joined:
    Oct 8, 2020
    Posts:
    5
    Hi both,

    Thanks for getting in touch and providing this feedback. Sadly, Graham Dunnett passed away early this year. He was hugely influential across the company and within the community as well, including the forums, and he's dearly missed.

    Unfortunately, I've not been able to find out whether Graham had made any progress on this issue. The documentation team is aware that the Order of Execution of Event Functions page is outdated and a member of the Core docs team has already started working on overhauling the page in the past few weeks.

    I can't promise a concrete timescale for when the update will go live, but it is definitely something we are working on. I'll leave the thread open for now and will post a reply in here when the page update does go live.

    Apologies for the time it's taken to address this and thanks for your patience, both in waiting for replies here and for the fixes we're working on for the page itself.
     
  11. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    Thanks for keeping us updated and sympathies to Graham's colleagues.
     
    jamesb-unity likes this.
  12. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    812
    Hi James, thanks for the quick reply, and likewise, extending my sympathies to Graham's family and colleagues.
     
    jamesb-unity likes this.