Search Unity

Question How does Awake() work with regards to "yield null return"?

Discussion in 'Editor & General Support' started by IIBearWithII, Apr 30, 2023.

  1. IIBearWithII

    IIBearWithII

    Joined:
    Feb 15, 2023
    Posts:
    87
    If I have several scripts runnings code in Awake(), and one of them has a loop that includes a "yield null return", will all of the other scripts guaranteed run their Awake() methods at least once before the script with the loop runs the next loop? I know that "yield null return" delays until the next frame, but I don't really know what that actually means... will all awake methods run once per frame?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,747
    IIBearWithII likes this.
  3. IIBearWithII

    IIBearWithII

    Joined:
    Feb 15, 2023
    Posts:
    87
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,747
    I assume you mean Awake calls StartCoroutine on an instance of the IEnumerator?

    Otherwise if you just invoked the IEnumerator, isn't running.

    Coroutines in a nutshell:

    https://forum.unity.com/threads/des...en-restarting-the-scene.1044247/#post-6758470

    https://forum.unity.com/threads/proper-way-to-stop-coroutine.704210/#post-4707821

    Splitting up larger tasks in coroutines:

    https://forum.unity.com/threads/bes...ion-so-its-non-blocking.1108901/#post-7135529

    Coroutines are NOT always an appropriate solution: know when to use them!

    https://forum.unity.com/threads/things-to-check-before-starting-a-coroutine.1177055/#post-7538972

    https://forum.unity.com/threads/heartbeat-courutine-fx.1146062/#post-7358312

    Our very own Bunny83 has also provided a Coroutine Crash Course:

    https://answers.unity.com/questions...ected.html?childToView=1749714#answer-1749714


    Here is some timing diagram help:

    https://docs.unity3d.com/Manual/ExecutionOrder.html
     
    IIBearWithII likes this.
  5. IIBearWithII

    IIBearWithII

    Joined:
    Feb 15, 2023
    Posts:
    87
    I guess what I really need to know is "what is a frame?"

    What actually gets done in one frame before Unity decides to move on to the next? Especially with regards to the beginning of a scene, when I'm just setting things up and haven't drawn anything yet...
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,747
    See timing diagram above.
     
  7. IIBearWithII

    IIBearWithII

    Joined:
    Feb 15, 2023
    Posts:
    87
    will do, thanks
     
  8. IIBearWithII

    IIBearWithII

    Joined:
    Feb 15, 2023
    Posts:
    87
    Sorry, trying to understand the timing diagram, but it's not making sense. I have some big gaps in knowledge I think. For example, in the Script Lifecycle Flowchart, is the act of running all Awake() methods considered one frame, and then when the flowchart moves on to executing all OnEnable() methods, is that considered the next frame?
     
  9. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,205
    No. Everything between and including the Physics and Pausing sections is just one frame. When a scene is started every Awake() on every enabled GameObject will execute before the first frame has started. Once all of those have executed OnEnable() will execute for every enabled script on every enabled GO. Finally after all of those Start() will execute for every enabled script on every enabled GO.

    Unity's Order of Executions page explains some of this but some of it is found on the pages for the API.

    https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html
    https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnEnable.html
    https://docs.unity3d.com/ScriptReference/MonoBehaviour.Start.html
     
    Last edited: May 1, 2023
    IIBearWithII and spiney199 like this.
  10. meredoth

    meredoth

    Joined:
    Jan 29, 2014
    Posts:
    8
    Actually Unity doesn't guarantee the order of execution between different scripts' Awake and OnEnable methods. Awake will be called before OnEnable for the same script, but an OnEnable in a script may be executed before the Awake of another script. The Start though is guaranteed to execute after all Awakes and OnEnables have finished executing.

    In my tests I haven't found a rule, about the order of execution between Awake and OnEnable on different scripts, although I think it has something to do with when the scripts were created and somehow registered in Unity internally.

    This can lead to subtle bugs, like calling in OnEnable a method from a different script, that uses a variable that gets initialized in that script's Awake method.

    Also as a side note, the Awake method will also be executed if a gemeobject is enabled but the script component is disabled, but for the OnEnable method to be executed both the gameobject and the script component have to be enabled.
     
    IIBearWithII and Ryiah like this.
  11. IIBearWithII

    IIBearWithII

    Joined:
    Feb 15, 2023
    Posts:
    87
    If a number of gameObjects run Awake, and one of them calls a coroutine that says "yield return null", will all of the other Awake methods guaranteed have run once before the Awake running the coroutine resumes?
     
  12. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,935
    Yes. As mentioned all Awake calls, on scene load, happen in the one frame.

    As an aside, at lot of these questions you can easily test yourself in Unity.
     
    IIBearWithII and Kurt-Dekker like this.
  13. IIBearWithII

    IIBearWithII

    Joined:
    Feb 15, 2023
    Posts:
    87
    Thanks!
     
  14. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,747
    This is really the best response to a wide range of simple Unity questions. Just make a quick script, drop it on a GameObject (or five), implement the callbacks you want and fill them with Debug.Log() methods and press PLAY.

    Now based on the output make sure you don't assume anything that isn't promised in the docs, such as order.
     
    spiney199 and meredoth like this.
  15. meredoth

    meredoth

    Joined:
    Jan 29, 2014
    Posts:
    8
    I haven't tested that. If I remember correctly, there was a situation I had seen once with OnEnable and Awake that OnEnable had a coroutine with yield return null and that allowed all the Awakes to finish before the OnEnable. It was implemented like that because in OnEnable an event was invoked that could call a method that was using fields that got initialized in Awake and that could throw a null reference if those fields weren't initialized.

    Eventually I think, we decided to call the event in the Start method and make a boolean true there, after that the code in the onEnable was checking that boolean, so the first time the event was invoked in Start and after that from the onEnable after each disable/enable of the game object.

    I think it was working with the coroutine also, the other awakes had finished before the onEnable with the coroutine got called.