Search Unity

How to do Additive Scene Preloading

Discussion in 'Scripting' started by Kastenfrosch2, Jun 21, 2020.

  1. Kastenfrosch2

    Kastenfrosch2

    Joined:
    Mar 19, 2017
    Posts:
    10
    Assumption:
    • MainScene
      • Should always be open
    • Scene-A, Scene-B
      • Additively loaded on top of MainScene
      • Only one scene active at once

    Lets imagine I'm in Scene-A and want to preload Scene-B.
    I tried the following:
    • Load Scene-B (Additively, Async), but forbid activation
    • After B-Load completed: Unload Scene-A
    • After A-Unload completed: Allow Activation of Scene-B
    Visualization.jpg

    However this does not work, as Unloading of Scene-A does not start before Scene-B was activated.

    Code (CSharp):
    1.  
    2. public IEnumerator SwitchScenes(string loadSceneName, string unloadSceneName)
    3. {
    4.    AsyncOperation loadOperation = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(loadSceneName, LoadSceneMode.Additive);
    5.    loadOperation.priority = 0;
    6.    loadOperation.allowSceneActivation = false;
    7.  
    8.    while (loadOperation.progress < 0.9f)
    9.    {
    10.        yield return null;
    11.    }
    12.  
    13.    AsyncOperation unloadOperation = UnityEngine.SceneManagement.SceneManager.UnloadSceneAsync(unloadSceneName);
    14.    unloadOperation.priority = 1;
    15.  
    16.    // we'll wait the full time :(
    17.    yield return new WaitForSeconds(100.0f);
    18.  
    19.    loadOperation.allowSceneActivation = true;
    20. }
    21.  
    Here someone said, that this is in general not possible in Unity.

    Does that really mean, that preloading additively loaded exclusive scenes is not properly possible with Unity or is there any workaround?

    I heard about "faking" the unloading of Scene-A by deactivating all its GameObjects manually, then Activating Scene-B and then "properly" unloading Scene-A, but that sounds really hacky...
     
    Last edited: Jun 21, 2020
  2. I yet to see any real use cases where it was crucial to unload a scene before the activation of the new one. Could you describe yours? I'm genuinely interested.
    I understand what you're trying to do, and yes, it is not working because of the Async queue. First you need to finish the activation (finis the task) and then the unloadasync can finish as well.
    But does it really matter? Or it is just the category of nitpick?
     
  3. Kastenfrosch2

    Kastenfrosch2

    Joined:
    Mar 19, 2017
    Posts:
    10
    I'm sure i could work around all those cases that rely on scene-exclusiveness, but with that exclusiveness-guarantee some things are just easier:

    For example I have some objects that only make sense if exactly one of them is at present at a time (lets imagine it's the "Level Start Point"). Without the guarantee, my consistency checks (assert(count == 1)) fire up if I load the new "Start Point" because the old "Start Point" still exists. Or objects that "do some precalculations based on the spawn point" in their initialization could now see both of them.

    I think in general it just seems like a bad design, if during the initialization of an object, this object "sees" hundreds of other objects that will just be unloaded in a few milliseconds, though on paper those are from different scenes and should never interact with each other.

    (All arguments are for "why it would be cool to deactivate all game objects of the old scene before activating the new scene" - which i'd consider best solved by unloading one scene before activating another one)