Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Question what is the behavior of scene.isLoaded?

Discussion in 'Scripting' started by laurentlavigne, Apr 13, 2021.

  1. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,996
    I thought that a scene loaded additively would show isLoaded=true even if another scene is active but that's not the case.

    What is isLoaded for? It only works with Active scene?

    upload_2021-4-13_15-7-54.png
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,780
    The Scene object is mildly annoying: it's actually a value type, NOT a reference type:

    https://docs.unity3d.com/ScriptReference/SceneManagement.Scene.html

    Specifically,

    Scene: struct in UnityEngine.SceneManagement


    and not a class.

    This means if you get a Scene to your local variable, you just made a full copy of the data.

    If you then talk with the Scene Manager to do some stuff to that Scene, your old copy is now potentially out of date.
     
  3. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,923
    There is a loadingState which says it is still loading. I think you have checked too early.

    I tested with this code:
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.SceneManagement;
    4.  
    5. public  class Test: MonoBehaviour
    6. {
    7.     private IEnumerator  Start()
    8.     {
    9.         var op = SceneManager.LoadSceneAsync(sceneBuildIndex: 1, LoadSceneMode.Additive);
    10.    
    11.         while (!op.isDone) yield return null;
    12.  
    13.         var scene = SceneManager.GetSceneByBuildIndex(buildIndex: 1);
    14.         Debug.Log($"First additive scene loaded: {scene.isLoaded}");
    15.     }
    16. }
    screenshot1.png
     
    laurentlavigne likes this.
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,780
    This is also possible. I think scenes load for some amount of time and then they are loaded but grayed out if you pause the inspector then.

    They don't truly activate until after the end of the current frame, so that can be another wiggly bit.
     
    laurentlavigne likes this.
  5. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,923
    Oh yes, that too. Scene loading is done in the next frame.

    https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadScene.html
     
    laurentlavigne and Kurt-Dekker like this.
  6. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,996
    what if the scene is drag and dropped in the hierarchy window, then i press play, does it need one frame to register as loaded?

    what do you guys use in your project to control scene loading and availability? loadasync acts super weird some times, downright broken when a timeline is playing
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,780
    Pretty sure that's a copy. :)

    I use lots of LoadScenes, all of them additive after the first one, then just get down to business.

    I write all my inter-scene scripts to tolerate waiting for stuff to appear, e.g., the player tries to find a spawnpoint and if there isn't one, he yields one frame and tries again.
     
    laurentlavigne likes this.
  8. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,996
    i know what a copy of prefab is, it's an instance, asset = copy of the file but what's a copy of a scene?
    talking about this by the way
    upload_2021-4-13_16-5-23.png

    not async?

    how do you find stuff across scene? i have singletonite on this game :D
     
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,780
    It's a copy of that Scene struct.

    If you assign an int to another int, you made a copy (int is a struct)

    If you assign a Vector3 to another Vector3, you made a copy.

    If you assign a GameObject to another GameObject, now they are both pointing at the same one.

    It's just basic C# value vs reference types.

    Rarely.

    Usually by tagging it with something, most often an otherwise empty MonoBehavior. I don't like using Unity tags because they are inflexible and don't show up in the code very well.

    The otherwise empty MonoBehavior lets me also implement OnDrawGizmos() to make it more-visible in editor.
     
  10. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,923
    When you add more scenes for editing, it is VERY important, you only add them in the editor. They will be loaded when you hit the play button instantly. If they are loaded in the hierarchy. If you unload them (right-click/unload scene) or add them by holding the ALT while dropping them, they will be unloaded.

    But, in build, it doesn't matter. Only your main scene will be loaded (index: 0), nothing else. You're responsible to load them by code.

    I use a manager scene where all my game manager stuff live. It is the zero scene and it is responsible for loading and unloading everything else. I use roughly the same code (obviously I have a bunch of static public methods to handle it from anywhere) I posted above. Always additive, always async.
     
    Last edited: Apr 14, 2021
  11. BourbonBristles

    BourbonBristles

    Joined:
    Jan 23, 2014
    Posts:
    7
    For anyone else, when checking the current scene remember to check
    scene.isLoaded
    in
    Start
    or later as during
    Awake
    that value will still be false.
     
    Nit_Ram likes this.