Search Unity

Feature Request Initialization Scene

Discussion in 'Editor & General Support' started by CaseyHofland, Jan 11, 2021.

  1. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    613
    I have written a very useful script: it does 1 thing. If I have a scene called "DontDestroyOnLoad", it will automatically put all its root Objects in the 'real' DontDestroyOnLoad environment. So: an initialization scene that can be easily tweaked by designers.

    Now as much as I'm against Singletons, if you use some open source or asset store code, chances are it uses this pattern, and a great way to deal with it is putting it in my DontDestroyOnLoad scene.

    I wonder if Unity couldn't support this feature natively! I understand the exact naming of "DontDestroyOnLoad" is hard because there is no certainty it won't break some projects, but a simple toggle saying "Preload scene" in the scene's asset or the buildsettings could work the same.

    I know about Peloaded Assets but those aren't exactly designer-friendly.

    And to all who want this beautiful functionality for themselves:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.SceneManagement;
    3.  
    4. public static class DynamicDontDestroyOnLoad
    5. {
    6.     private const string sceneName = nameof(Object.DontDestroyOnLoad);
    7.  
    8.     [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    9.     private static void BeforeSceneLoad()
    10.     {
    11.         if(SceneUtility.GetBuildIndexByScenePath(sceneName) == -1)
    12.         {
    13.             return;
    14.         }
    15.  
    16.         SceneManager.sceneLoaded += SceneLoaded;
    17.  
    18.         var scene = SceneManager.GetSceneByName(sceneName);
    19.         if(scene.isLoaded)
    20.         {
    21.             SceneLoaded(scene, LoadSceneMode.Additive);
    22.         }
    23.         else
    24.         {
    25.             SceneManager.LoadScene(sceneName, LoadSceneMode.Additive);
    26.         }
    27.     }
    28.  
    29.     private static void SceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
    30.     {
    31.         if(scene.name == sceneName)
    32.         {
    33.             SceneManager.sceneLoaded -= SceneLoaded;
    34.  
    35.             var rootGameObjects = scene.GetRootGameObjects();
    36.             for(int i = rootGameObjects.Length - 1; i >= 0; i--)
    37.             {
    38.                 var rootGameObject = rootGameObjects[i];
    39.                 Object.DontDestroyOnLoad(rootGameObject);
    40.             }
    41.  
    42.             SceneManager.UnloadSceneAsync(scene, UnloadSceneOptions.UnloadAllEmbeddedSceneObjects);
    43.         }
    44.     }
    45. }
    46.  
     
    cmdexecutor and Madgvox like this.