Skip to main content

๐Ÿงฉ 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 DontDestroyOnLoad for 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.

Unity Hierarchy window with three additively-loaded scenes A recreation of Unity's Hierarchy window showing three scene headers. Manager (marked active/bold) contains GameManager, AudioManager and SaveSystem. Level_1 contains Environment, Enemies and Player. UI contains Canvas_HUD and EventSystem. Each scene header has an expand triangle. Hierarchy ๐Ÿ” Searchโ€ฆ โ–พ Manager (active) ๐ŸงŠ GameManager ๐ŸงŠ AudioManager ๐ŸงŠ SaveSystem โ–พ Level_1 (streamed) ๐Ÿ“ฆ Environment ๐Ÿ“ฆ Enemies ๐Ÿ“ฆ Player โ–พ UI (overlay) ๐Ÿ–ผ๏ธ Canvas_HUD ๐Ÿ–ผ๏ธ EventSystem Three scenes, one running game. Manager persists across levels ยท Level_1 swaps out ยท UI stays as an overlay. The bold scene name is the active scene โ€” new objects spawn there.
Figure 1: The Hierarchy with three additively-loaded scenes (faithfully recreated). Manager is bold because it is the active scene. Each scene owns its own root objects, but they all run together as one game.

โœ… 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:

flowchart TD A["Boot: load Manager scene
(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.
  • UnloadSceneAsync removes the objects, but the assets they referenced (textures, meshes) may linger. Call Resources.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 ago UnloadScene (synchronous) existed and is now deprecated. Always use UnloadSceneAsync โ€” 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.

  1. Create a Manager scene with an empty GameManager object that logs its own instance id in Awake (to prove it isn't recreated).
  2. At boot, additively load Level_1 and call SetActiveScene on it.
  3. Add a button (or key) that unloads the current level with UnloadSceneAsync, then additively loads Level_2 and activates it.
  4. 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.Additive loads 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 Instantiate calls โ€” set it with SetActiveScene after loading a level.
  • Release additive scenes with UnloadSceneAsync; follow with Resources.UnloadUnusedAssets() to reclaim memory. Unity always keeps at least one scene loaded.
  • DontDestroyOnLoad keeps an object alive across Single-mode loads โ€” always pair it with an Instance guard to prevent duplicate managers.
  • A persistent Manager scene often replaces the need for DontDestroyOnLoad entirely.

๐Ÿš€ 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.