Search Unity

Discussion A Comprehensive Guide to the Execution Order of Unity Event Functions

Discussion in 'Scripting' started by Edy, Jan 3, 2023.

  1. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Update: V2 released

    The section Order of execution for event functions in the Unity manual, while detailed and exhaustive, is confusing to say the least, where not directly wrong and/or misleading. Other similar diagrams found over the internet include similar imprecise or misleading information, probably influenced by the Unity manual.

    Even as an experienced Unity developer I also encounter issues in my own code related to not entirely counting on how the Unity event functions actually work. Also I often see third-party code making questionable use of the event functions, specially about initialization and finalization, which leads to issues and exceptions on common situations such as disabling and re-enabling components, or recompiling the scripts while in play mode (domain reload).

    So I decided to create a correct diagram showing the actual execution order of the main Unity event functions and the considerations every developer should know about. I'm also including essential information to help understand when and how to use each event method, and the consequences of doing so.

    Guide-to-the-Execution-Order-of-Unity-Event-Functions-V2-Light.png

    Other event functions not included in this diagram can be found in the original execution order page in the Unity manual. You can easily locate their place in this diagram by consulting the manual.

    This guide is available in other resolutions and formats, including PDFs and a "Dark Mode" version, here:
    https://www.edy.es/dev/docs/a-comprehensive-guide-to-the-execution-order-of-unity-event-functions/

    Guide-to-the-Execution-Order-of-Unity-Event-Functions-V2-Light.png Guide-to-the-Execution-Order-of-Unity-Event-Functions-V2-Dark.png

    Feel free to let me know if there's anything unclear in the diagram or the information. I know there could be many more events and details here, but I prefer to keep it with the strictly necessary information to understand the actual execution flow.
     
    Last edited: Jun 5, 2023
    CodeSmile, vozcn, sawnch and 14 others like this.
  2. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    upload_2023-1-3_21-11-28.png

    For all intents and purposes completely true! But to be annoying, technically not entirely. On Demand Rendering can alter this, for example this property shows that sometimes an Update call is not done for every visually presented frame.
     
    oscarAbraham and Edy like this.
  3. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Good one, thanks for pointing it out! This seems a corner case introduced in Unity 2019.3. If I've understood it correctly, the Update call still happens normally, with a correct Time.deltaTime, etc. Only the block "Scene Rendering" in the diagram wouldn't actually render a frame sometimes.

    If this case becomes relevant enough it may deserve adding a new footnote to the diagram. For now, I'm trying to keep the information to the minimum according to the default Unity settings.

    Anyone feel free to remark any other corner or specific cases, so we could have them documented here!

    EDIT: After reviewing this in depth I came to the conclusion that rephrasing the sentence to

    - Called before processing each visually presented frame

    would make the statement entirely true regardless of the On Demand Rendering feature. Update is called for each display frame. If On Demand Rendering is set not to render the scene then the previously rendered frame will still be visible for the current display frame. Only the "Scene Rendering" part of the diagram would be skipped.
     
    Last edited: Jan 5, 2023
  4. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,440
    One thing I didn't want to write a whole test case to answer for myself is whether a created object's Awake is called before InstantiateObject returns or not; I know Start() happens potentially much later. Thanks for including that exact verbiage. There might be no good way to show this "non-aligned" relationship between two objects in the diagram without spelling it out verbally.

    The original state diagram also shows how Reset() is called if you're in the editor, and also where in the loop all your Coroutines get serviced. Not sure if you wanted to cover all those bases too.
     
    Edy likes this.
  5. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Not for now. These may be located easily in this diagram once you look at the original one.

    I wanted to keep this diagram to the essentials because I've found that people new to Unity have significant difficulty understanding the basics of how component scripts work. The original diagram doesn't help with this at all. I hope mine will lower the barrier to entry and make it easier for people to understand.
     
    Melanie_MICA and Kurt-Dekker like this.
  6. Unifikation

    Unifikation

    Joined:
    Jan 4, 2023
    Posts:
    1,086
    Is OnEnable() also called when an object is already active and the script is already active and Play mode is entered? IOW, not only when the Object is actively set to enabled by a script, but also on entering Playmode (and Scene Loading where it's on an object that's active on loading and the script is active)?
     
  7. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Yes, of course. Loading a scene is equivalent to instance all the GameObjects and Components, but it's done from the Unity code. This happens when entering the Play mode or when loading a scene in runtime. Components pass through all the stages: Awake, OnEnable, Start, etc. Likewise, when unloading the scene or exiting the Play mode the GameObjects are destroyed by Unity, so the ending stages (OnDisable, Destroy) apply as well.
     
    Unifikation likes this.
  8. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    I also needed it, and I've been programming in Unity for 13 years now xD
     
  9. MehdiZarei

    MehdiZarei

    Joined:
    Mar 22, 2019
    Posts:
    2
    Thank you for the diagram, solved some misunderstandings for me especially for Awake and OnEnable callbacks.

    Just one note, I think for the FixedUpdate we should use Time.fixedDeltaTime rather than using Time.deltaTime, or am I misunderstood again?
     
    Edy likes this.
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,481
    Unity already implicitly passes the fixed delta-time when you read Time.deltaTime during the script Fixed-Update. I guess all those years ago, too many users were making this mistake.

    See the docs here.
     
  11. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    As MelvMay said. Just for additional clarification, the best practice is to use Time.deltaTime from both Update and FixedUpdate. The property will return the correct value depending on where it's read from.
     
    Last edited: Jan 6, 2023
    MehdiZarei and MelvMay like this.
  12. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
  13. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,435
    Random questions
    - OnDisabled gets called if destroy gameobject destroy/destroyimmediate?
    - Does new input system happen on that internal input update spot also?
     
  14. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,923
    OnDisable will be called before OnDestroy when a Unity object (not just game objects) are destroyed, yes.

    The New Input System has options for updating in Update and Fixed Update. I believe the package hooks into the player loop to recieve its updates. I wouldn't know where in player loop they specifically reside though.
     
    Edy likes this.
  15. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Yes. Every solid line in this diagram will be forcefully followed during the lifecycle of any MonoBehaviour. Dashed lines or multiple path choices depend on specific events or conditions (see the corresponding remarks).
     
  16. iileychen

    iileychen

    Joined:
    Oct 13, 2015
    Posts:
    110
    Great!
    How about events in the order, for example OnPointerClick etc.
     
  17. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Those may be easily located here by looking at the original diagram from the Unity manual. Indeed, those are enclosed within the "Internal Input Update" block called right before Update, after the Internal Input Update. I wanted to leave this diagram with the minimum essentials.
     
    Last edited: Apr 6, 2023
  18. iileychen

    iileychen

    Joined:
    Oct 13, 2015
    Posts:
    110
    I see, just another curious, does the "Internal Input Update" block always invoked before "Update" between different MonoBehaviour instances, for example:
    Code (CSharp):
    1. class A{
    2.  
    3. OnPointerDown() ...
    4.  
    5. }
    6.  
    7. class B{
    8.  
    9. Update()
    10.  
    11. }
    For my testing, i need to change the Executing order in the project setting to place B after A, to ensure every time A.OnPointerDown() will be called before B.Update in a frame.

    But, I am not very sure.
     
  19. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    As for my understanding, the "Internal Update Block" itself doesn't trigger any event function, it just reads the input devices and updates the internal values in Unity. Then the corresponding event functions are called for each MonoBehaviour instance based on the new input state, and applying the execution order. I've edited my previous reply for clarification.
     
    Last edited: Apr 7, 2023