Search Unity

OnLevelWasLoaded does fire even if the scene is in fact not displayed yet?

Discussion in 'Scripting' started by rapidrunner, Feb 29, 2016.

  1. rapidrunner

    rapidrunner

    Joined:
    Jun 11, 2008
    Posts:
    944
    I am curious to understand when this event fire.

    I have scene 0, from it I load scene 1 through a game manager. So far so good.

    Now, I was tweaking timing to change something in the loaded scene, and figured out that OnLevelWasLoaded, in fact fire before the start function, of a script which is in the loaded screen.

    I did put a breakpoint on that function, and in fact, when that event fire up, none of the objects in that scene, is displayed in the game window; nor in the inspector. Which means that they are in fact, not instantiated yet.

    My understanding was that once that the scene is loaded, this event will fire up; which should correspond roughly at the same time of an awake function in any of the gameobjects in the loaded scene.
    Not sure what is the point of OnLevelWasLoaded, if in fact you do not have access to any of the objects in the new scene.
     
  2. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,332
    The order is, as far as I know:

    - You call LoadLevel in some script
    - at the end of the same frame, the old level is unloaded, any object that is not set to DontDestroyOnLoad is destroyed (OnDestroy will be called). This does not happen on an LoadLevelAdditive
    - the new level is loaded - every object in that level is created.
    - OnLevelWasLoaded is fired on every MonoBehaviour that defines it
    - Awake is called
    - Start is called
    - The first Update is called, and things start drawing

    I might be wrong about details here, but what I am certain about is that Awake is called after OnLevelWasLoaded. Which is a major inconvenience, but I doubt a suggestion to change that would go through.
     
    rapidrunner likes this.
  3. rapidrunner

    rapidrunner

    Joined:
    Jun 11, 2008
    Posts:
    944
    Much appreciated; Baste.

    From what I can see; when the debugger is attached (VS); when OnLevelWasLoaded is called, the inspector show nothing from the new scene.

    Although I was able to work around in the Awake function, creating the references to the gameobjects that I needed.

    Not sure if this is a bug or if the order that you mentioned is not exactly as you wrote it.
     
  4. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    as far as I can tell, OnLevelWasLoaded is machine-dependent so it could be called before Awake() on one machine but after on another. I believe this is one of the reasons its specifically ommited in the Script execution order page. however it should always fire before the first call to Update in a scene.

    in Unity 5 there's an attribute [RuntimeInitializeOnLoadMethod] (which you'd attach to a static method) that functions similar to OnLevelWasLoaded and by default it always calls after the Awake frame. its not Monobehaviour-specific so you can even use it in non-mono classes.

    in the most recent versions (I think 5.3.x) the attribute can now come with a parameter
    Code (CSharp):
    1. [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    2. // call this function onLevelWasLoaded before Awake
    3. void static Before(){}
    4.  
    5.  
    6. [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
    7. //call this function onLevelWasLoaded after Awake
    8. void static After(){}
     
    rapidrunner likes this.
  5. rapidrunner

    rapidrunner

    Joined:
    Jun 11, 2008
    Posts:
    944

    Thanks, that's a good point that you made.