Best way to reload an additive scene?

I created a separate scene for UI and managers, and individual scenes for game levels. At runtime, I load them together additively.
When the player dies, I want to reload the level scene.

Currently, my code looks like this:

public UnityEvent<string> OnReload;

private void Reset()
{
    OnReload?.Invoke(""); // triggers the loading animation
    Invoke(nameof(UnloadAndReload), 1.35f);
}

private void UnloadAndReload()
{
    SceneManager.UnloadSceneAsync(CurrentLevel.SceneReference.BuildIndex).completed += operation =>
    {
        SceneManager.LoadScene(CurrentLevel.SceneReference.BuildIndex, LoadSceneMode.Additive);
    };
}

The UnityEvent triggers a loading animation, which I use to hide the screen blink during scene reloading.
But I’m not sure if this is the best practice.

My questions are:

  1. Is it necessary to call SceneManager.LoadScene after UnloadSceneAsync.completed?
    Or is it fine to just write it like this?
private void UnloadAndReload()
{
    SceneManager.UnloadSceneAsync(CurrentLevel.SceneReference.BuildIndex);
    SceneManager.LoadScene(CurrentLevel.SceneReference.BuildIndex, LoadSceneMode.Additive);
}
  1. What exactly happens when I call UnloadSceneAsync?
  • Are all GameObject references in that scene set to null immediately?
  • Could it happen that the same scene exists twice in memory at the same time? (I’m worried because I still use Find() to get references, and I don’t want duplicate objects to cause issues or crashes.)
  • What parts of the scene are actually unloaded asynchronously in backend?

Unloading a scene is more akin to everything in the scene being destroyed.

Scenes can be loaded more than once so it is possible to have two of the same scene present.

So to that end, for safety’s sake, you should definitely use async code or a coroutine to await the unload, potentially wait another frame, then load in the scene again.

You definitely don’t want to call UnloadSceneAsync and LoadScene one after the other, as the former will not complete synchronously. After all it returns a handle that tells you the status of the load operation.

Well, just try. :wink:

It takes longer to write a post about it.

But even with this unload-complete code snippet I’m pretty sure you want, or may even have to add a 1-frame delay so that you’re not loading in new content while unloaded scene’s objects may not have been fully removed from memory. This could increase memory pressure.

I’m not sure whether unload will be considered complete when the scene’s objects are merely scheduled for destroy at the end of the frame, or whether it will actually wait until the next frame.