๐งฉ Lesson 5.2: Additive & Multi-Scene Workflows
Single-mode loading throws away the old scene to make room for the new one. But sometimes you want things to stay: a manager that owns your audio and save system, a UI overlay, a persistent player. Additive loading stacks scenes on top of each other so several are live at once. It's how big games stream open worlds and how clean projects separate concerns. Let's learn to stack them and, just as importantly, to tear them down.
๐ฏ Learning Objectives
By the end of this lesson, you will be able to:
- Load a scene alongside others with
LoadSceneMode.Additive - Structure a game as a persistent Manager scene plus streamed level scenes
- Control which additive scene new objects spawn into with
SetActiveScene - Unload a scene cleanly with
UnloadSceneAsync - Use
DontDestroyOnLoadfor cross-scene singletons โ and avoid its duplicate-manager pitfall - Choose between an additive Manager scene and
DontDestroyOnLoad
Estimated Time: 40 minutes ยท Prerequisite: Lesson 5.1 (Loading Scenes)
In This Lesson
Stacking Scenes: Additive Mode
In Lesson 5.1 every load was LoadSceneMode.Single โ it wiped the current scene first. Switch the mode to Additive and the new scene loads on top, with the existing one still running:
using UnityEngine.SceneManagement;
// Keep whatever is loaded; add Level_1 alongside it.
SceneManager.LoadScene("Level_1", LoadSceneMode.Additive);
// Async additive โ the usual choice for streaming a level.
AsyncOperation op = SceneManager.LoadSceneAsync("Level_1", LoadSceneMode.Additive);
Now two (or more) scenes are live simultaneously. Their root GameObjects all appear in the Hierarchy under separate scene headers, they all get Update ticks, and their objects can see each other. This unlocks a powerful structure: a small, permanent scene that owns your game's systems, plus level scenes that come and go.
๐ Definition
Additive loading: loading a scene without unloading the current one, so multiple scenes are active at the same time. Each keeps its own root objects and lighting; together they form one combined runtime world. The opposite of Single mode, which allows only one scene at a time.
The Multi-Scene Hierarchy
When several scenes are loaded additively, the Hierarchy window groups objects under one header per scene. Here's a typical setup: a permanent Manager scene, the current Level_1, and a separate UI overlay scene, all loaded together.
โ Pro Tip
Splitting your game into a Manager scene, level scenes, and a UI scene lets teammates work on different scenes without merge conflicts, and lets you test a level scene in isolation just by opening it. This "multi-scene editing" is exactly how larger Unity projects stay organized.
The Active Scene
With several scenes loaded, Unity needs to know which one is "in charge" for a few defaults. That's the active scene (bold in the Hierarchy). It decides:
- Where newly
Instantiated objects go if you don't say otherwise. - Which scene's lighting and skybox settings are used for the render.
After you additively load a level, promote it to active so spawns and lighting come from it, not the Manager scene:
using UnityEngine.SceneManagement;
using System.Collections;
IEnumerator LoadLevel(string sceneName)
{
// 1) Stream the level in alongside the Manager scene.
yield return SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
// 2) Make it the active scene so its lighting + new spawns apply.
Scene level = SceneManager.GetSceneByName(sceneName);
SceneManager.SetActiveScene(level);
}
yield return on the AsyncOperation is a tidy trick: a coroutine will pause on it until the load finishes, so line 2 only runs once the scene actually exists. Skip the wait and GetSceneByName may return an invalid scene.
โ ๏ธ Forgetting to SetActiveScene
Load a level additively but leave the Manager scene active, and your level's baked lighting and skybox are ignored โ the world looks flat or wrong. Worse, everything you Instantiate lands in the Manager scene and won't unload with the level. Always SetActiveScene to the level after loading it.
Streaming Levels In & Out
Put it together and you get a clean level-swap: unload the old level, load the new one, activate it โ all while the Manager and UI scenes never blink. Here's the lifecycle:
(Single)"] --> B["Additively load UI overlay"] B --> C["Additively load Level_1
+ SetActiveScene(Level_1)"] C --> D["Play Level_1โฆ"] D --> E{"Go to Level_2?"} E -- "Yes" --> F["UnloadSceneAsync(Level_1)"] F --> G["Additively load Level_2
+ SetActiveScene(Level_2)"] G --> D E -- "No" --> H["Manager & UI persist the
whole session"]
Figure 2: The streaming loop. The Manager and UI scenes load once and stay; level scenes are added and unloaded as the player progresses.
Notice the Manager scene loads with Single once at boot (clearing whatever came before), and everything after is additive. That guarantees exactly one Manager scene for the whole session.
Unloading with UnloadSceneAsync
Additive scenes don't clean themselves up โ load ten levels additively without unloading and you'll have ten levels' worth of objects churning in memory. When you're done with a scene, release it with SceneManager.UnloadSceneAsync:
// Unload a specific level scene by name.
yield return SceneManager.UnloadSceneAsync("Level_1");
// Optional: reclaim the memory its assets used.
yield return Resources.UnloadUnusedAssets();
Two things to know:
- Unloading destroys that scene's GameObjects only. The other loaded scenes (Manager, UI) are untouched โ that's the whole point.
UnloadSceneAsyncremoves the objects, but the assets they referenced (textures, meshes) may linger. CallResources.UnloadUnusedAssets()afterward to actually free that memory.
โ ๏ธ You can't unload the last scene
Unity always needs at least one loaded scene. If you try to unload the only remaining scene, the call fails. In practice this is fine โ your Manager scene stays loaded the whole time โ but it's why you unload the old level only after loading the new one (or while the Manager scene is still present).
๐ก There's an older name too. Long agoUnloadScene(synchronous) existed and is now deprecated. Always useUnloadSceneAsyncโ it spreads the teardown across frames just like async loading, so a big level unloads without a hitch.
DontDestroyOnLoad & Its Pitfall
There's a second way to keep something alive across scenes, and you'll see it everywhere: DontDestroyOnLoad. Call it on a GameObject and Unity moves it to a special hidden scene that survives every Single-mode load.
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; private set; }
void Awake()
{
// Classic persistent-singleton guard.
if (Instance != null && Instance != this)
{
Destroy(gameObject); // a duplicate arrived โ kill it
return;
}
Instance = this;
DontDestroyOnLoad(gameObject); // survive scene loads
}
}
The guard clause is not optional โ it's the fix for the pitfall. Here's the trap:
โ ๏ธ The duplicate-manager pitfall
Put a GameManager in your MainMenu scene and in Level_1. Player starts at the menu โ one manager is created and marked DontDestroyOnLoad. They load Level_1 (Single mode) โ the menu's manager survives, but Level_1 also contains a GameManager, so now there are two. Audio double-plays, save state forks, chaos. The if (Instance != null) Destroy(...) guard above makes the second one delete itself the instant it wakes up.
So which do you reach for โ a persistent Manager scene (Figure 1) or DontDestroyOnLoad on a single object?
- Manager scene (additive): visible in the Hierarchy, easy to inspect and edit, no hidden scene. Best when you have several persistent systems and use additive loading anyway.
- DontDestroyOnLoad: lightweight, works even with plain Single-mode loading, no extra scene to set up. Best for one or two singletons in a simpler project. Always pair it with the guard.
โ Pro Tip
Don't mix both approaches for the same system. Pick one home for each manager. And remember: if you use a persistent Manager scene, you usually don't need DontDestroyOnLoad at all โ the scene itself never unloads, so its objects already persist.
Hands-on Challenge
๐๏ธ Exercise 1: A persistent Manager + swappable levels
Objective: Build the structure in Figure 1 and swap levels without losing your manager.
- Create a
Managerscene with an emptyGameManagerobject that logs its own instance id inAwake(to prove it isn't recreated). - At boot, additively load
Level_1and callSetActiveSceneon it. - Add a button (or key) that unloads the current level with
UnloadSceneAsync, then additively loadsLevel_2and activates it. - Watch the Console: the GameManager's id should print once and never change, even as levels swap.
๐ก Hint: my level's lighting looks wrong after swapping
You forgot SetActiveScene on the newly loaded level, so Unity is still using the Manager scene's (empty) lighting settings. Set the level active right after its async load finishes.
โ Success check
Levels swap in and out while the Manager scene stays put in the Hierarchy; the GameManager logs its id exactly once for the whole session; and each level renders with its own lighting.
๐๏ธ Exercise 2: Break, then fix, the duplicate manager
Deliberately put a GameManager (with DontDestroyOnLoad but no guard) in two Single-mode scenes and load one from the other. Confirm two managers exist (log the count). Then add the if (Instance != null) Destroy(gameObject) guard and confirm the duplicate deletes itself. Seeing the bug and the fix side by side cements why the guard matters.
๐ฏ Quick Quiz
Question 1: What does LoadSceneMode.Additive do that Single mode doesn't?
Question 2: After additively loading a level, why call SetActiveScene on it?
Question 3: What is the guard if (Instance != null && Instance != this) Destroy(gameObject); protecting against?
Summary
๐ Key Takeaways
LoadSceneMode.Additiveloads a scene on top of the current one, so multiple scenes run together.- A common structure: a permanent Manager scene + streamed level scenes + a UI overlay scene.
- The active scene supplies lighting/skybox and receives new
Instantiatecalls โ set it withSetActiveSceneafter loading a level. - Release additive scenes with
UnloadSceneAsync; follow withResources.UnloadUnusedAssets()to reclaim memory. Unity always keeps at least one scene loaded. DontDestroyOnLoadkeeps an object alive across Single-mode loads โ always pair it with anInstanceguard to prevent duplicate managers.- A persistent Manager scene often replaces the need for
DontDestroyOnLoadentirely.
๐ What's Next?
You can now move around a multi-scene game without losing your systems. But nothing you've done yet survives quitting โ reload the game and every score, setting, and unlock is gone. In Lesson 5.3: Saving with PlayerPrefs we make small pieces of data stick between sessions.
๐งฉ You can stack and stream scenes now
Additive loading, an active scene, clean unloading, and a persistent manager โ the toolkit behind menus that never blink and worlds that stream in as you walk.