Switching scenes: LoadScene, loading screens and what survives
How do I switch to another scene?
Add every scene to the Scene List in File > Build Profiles, then call SceneManager.LoadScene with its name. The swap happens on the next frame, everything in the old scene is destroyed, and only root objects marked DontDestroyOnLoad survive — along with static fields and Time.timeScale, which nothing resets for you.
Loading another scene is one line. Everything that goes wrong with it happens around that line: the scene was never added to the build, the code after it kept running, or something you needed was thrown away with the old scene.
Step 1 — put the scene in the list
- 1
Open (called before Unity 6) and find the Scene List.
- 2
Open each scene you want in the game and press Add Open Scenes, or drag the .unity files in from the Project panel.
- 3
Whatever sits at index 0 is the scene the built game starts on. Put the menu, or the intro, at the top.
Step 2 — load it
using UnityEngine;
using UnityEngine.SceneManagement; // without this line, SceneManager is not found
public class Doorway : MonoBehaviour
{
public void Play()
{
SceneManager.LoadScene("Arena"); // by name, as spelt in the Scene List
}
public void Restart()
{
// The scene that is running, whatever it is called.
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}What survives the load, and what does not
Every GameObject in the old scene is destroyed. References held to them go null, and coroutines running on them stop where they are.
An object marked
DontDestroyOnLoadcarries on — but only if it is a root object, with no parent. Music, a save file in memory, and a manager are the usual ones.Static fields are not part of any scene, so they keep their values. That is handy for carrying a level number across, and a trap when a leftover value from the last run is still sitting there.
Time.timeScale is global. Pause the game with timeScale = 0, load the menu without putting it back to 1, and the menu opens frozen — with no error to explain why.
A loading screen, for scenes that take a moment
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Loader : MonoBehaviour
{
public Slider bar;
public void Load(string scene) => StartCoroutine(LoadRoutine(scene));
IEnumerator LoadRoutine(string scene)
{
AsyncOperation op = SceneManager.LoadSceneAsync(scene);
while (!op.isDone)
{
// progress stops at 0.9 while the scene waits its turn to appear,
// so scale it back up or the bar never reaches the end.
bar.value = Mathf.Clamp01(op.progress / 0.9f);
yield return null;
}
}
}Two scenes at once
LoadSceneMode.Additive puts a scene on top of the one already running instead of replacing it: a HUD that never reloads, or a level streamed in beside a hub. Take it away again with UnloadSceneAsync, and remember that new objects are created in whichever scene is the active one.
the lesson that builds this
Screens, panels and the GameManager
This post is a standalone recipe. In the course, the same thing is built as part of the one project that runs through all five tabs — Basics, lesson 10.