1

I ran into this article Multi-scene editing, and at the bottom of the tips and tricks section, there's the following sentence: "It is recommended to avoid using DontDestroyOnLoad to persist manager GameObjects that you want to survive across scene loads. Instead, create a manager scene". I decided to try this out, since my current game has a manager which uses DontDestroyOnload().

Now say I have 3 scenes: 1) StartScene 2) Manager 3) Level_01

In StartScene, I do this to have the manager permanently loaded from the beginning:

void Start()
{
    SceneManager.LoadSceneAsync("Manager", LoadSceneMode.Additive);
}

In Manager, I have a script called SceneLoader

In SceneLoader, I do this:

void Update()
{
    Debug.Log(SceneManager.GetActiveScene().name);
}

public void LoadScene(string sceneName)
{
    StartCoroutine(LoadSceneAsync(sceneName));
}

IEnumerator LoadSceneAsync(string sceneName)
{
    Scene currentScene = SceneManager.GetActiveScene();
    AsyncOperation sceneLoadingOperation = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
    while(!sceneLoadingOperation.isDone)
    {
        yield return null;
    }
    SceneManager.UnloadSceneAsync(currentScene);
    SceneManager.SetActiveScene(SceneManager.GetSceneByName(sceneName));
}

I also have a button called Start. When I press the button, the method LoadScene() is called.

In Level_01, I do this:

void Start()
{
    Debug.Log("Level_01 start called");
}

Now here's the problem: I expect the Console output to be this:

StartScene (output by SceneManager.CurrentlyActiveScene)

Level_01 start called (output by Start() in Level_01)

Level_01 (output by SceneManager.CurrentlyActiveScene)

Instead, the Console output is this:

StartScene (output by SceneManager.CurrentlyActiveScene)

Level_01 start called (output by Start() in Level_01)

StartScene (output by SceneManager.CurrentlyActiveScene)

Level_01 (output by SceneManager.CurrentlyActiveScene)

Which means that the Start() function of the Level_01 scene is called BEFORE the CurrentlyActiveScene is set, and that the CurrentlyActiveScene is only set on the following frame.

Question: How can I make sure that the Start() function is only called after the CurrentlyActiveScene is set?

Thrindil
  • 143
  • 3
  • 17
  • well you scene is loaded async and the second `StartScene` is still from the first scene but the next frame. Afaik your new Scene counts a fully loaded when all Awake and Start methods are done. Maybe [this](https://forum.unity.com/threads/detect-when-scene-has-fully-loaded.532558/) helps – derHugo Jan 30 '20 at 15:32
  • You can subscribe to SceneManager.sceneLoaded which will trigger when scene is completely loaded (e.g. SceneManager.sceneLoaded += OnSceneLoaded;) – GhAyoub Jan 30 '20 at 16:23
  • @derHugo I tried subscribing to the SceneLoaded event to output a Debug.log(), but the results are exactly the same. I think your comment about a scene not being fully loaded before the Awake() and Start() methods are called is correct, based on this test. I also tried using yield return SceneManager.LoadSceneAsync("SceneNameHere"); in my coroutine, but that resulted in the manager scene getting unloaded. I'm also not sure about where that statement should be placed in the coroutine, so I might be using it wrong. – Thrindil Jan 31 '20 at 04:39
  • @GhAyoub Check my comment above, subscribing to the event resulted in the same output. So the event happens before the scene is set to active. – Thrindil Jan 31 '20 at 04:41

0 Answers0