Deep Dive

Multi-Scene Setup

Build a game with multiple levels, a title screen, and values (health, score) that carry between scenes. Two components do the work: GameSceneManager loads scenes and positions the player, and a simple checkbox keeps values alive across loads.

Load levels with one UnityEvent call
Health and score survive scene changes
Player spawns at the right entry point
Main menu loads any level

The Pattern

Two types of scene

Multi-scene games in EGTK use two types of scene. A bootstrap scene holds your player, managers, and UI — everything that needs to survive. Level scenes contain only the level content — geometry, collectibles, enemies, triggers.

Bootstrap Your first and only persistent scene
GameSceneManager
loads and unloads level scenes
Player (CharacterController)
survives all scene loads
GameHealthManager
optional — if health should persist
GameCollectionManager
optional — if score should persist
HUD Canvas / UI
stays visible across all levels
Level Scene One per level — loaded and unloaded
SpawnPoint
marks where the player appears on entry
Level geometry, props
the actual level content
Enemies, collectibles, triggers
wired locally to level managers
Exit trigger (optional)
calls GameSceneManager.LoadScene()
NO player, NO persistent managers
those live in the bootstrap scene
💡
Why additive loading?
GameSceneManager loads levels additively — the bootstrap scene stays loaded the whole time. This is what keeps the player, managers, and HUD alive. The level scene is loaded on top, then unloaded when you move to the next level. You never need to move the player between scenes.

Step by Step

Setting up scene loading

Six steps to go from a single scene to a multi-level game.

  1. 1
    Create the bootstrap scene
    Rename your existing scene to Bootstrap (or Title). This scene will be the one in Build Settings at index 0 — it is always the first scene Unity loads. Move your player and any managers you want to survive into it.
  2. 2
    Add GameSceneManager to the bootstrap scene
    Create an empty GameObject, name it SceneManager. Add the GameSceneManager component. Leave Use Additive Loading checked (default). Leave Unload Previous Scene checked. These defaults are correct for almost every game.
  3. 3
    Create a level scene
    File → New Scene. Save it as Level1. Add your level geometry here. Do not add a player or a camera rig — the player from the bootstrap scene will move into this level automatically.
  4. 4
    Add a SpawnPoint to the level scene
    Create an empty GameObject in Level1, name it SpawnPoint. Add the SpawnPoint component. Leave Is Default Spawn Point checked. Position it where the player should appear when entering the level. A green gizmo shows the exact spawn position in the Scene view.
  5. 5
    Add both scenes to Build Settings
    File → Build Settings → Add Open Scenes. Add Bootstrap first (index 0), then Level1. Every scene you want to load must appear in this list. The name shown in Build Settings is the string you pass to LoadScene().
  6. 6
    Wire a trigger to load the level
    Select your trigger object (InputTriggerZone, InputKeyPress, InputInteractionZone, etc.). In its event, drag in the SceneManager object. Choose GameSceneManager → LoadScene(string). Type Level1 in the string field. Press Play from the bootstrap scene and trigger it — Level1 loads in, the player is repositioned to the SpawnPoint.

How the pieces connect at runtime

🔖
Scene names are case-sensitive
The string you pass to LoadScene("Level1") must match the scene filename exactly, including capitalisation, with no path or .unity extension. If the scene isn't in Build Settings, Unity logs an error and onSceneLoadFailed fires.

Keeping values alive

Persist health, score, and inventory across levels

EGTK handles value persistence automatically — no extra setup needed beyond checking a box on each manager. The underlying system is completely invisible.

One checkbox per manager
Find the Scene Persistence section in the Inspector for GameHealthManager, GameCollectionManager, or GameInventoryManager. Check Persist Across Scenes. That's it. Values reset to their Inspector defaults at the start of each play session and survive every scene load during gameplay.
Persist Across Scenes
GameHealthManager
Health carries between levels. On the first level load, starts at Max Health. Add this manager to your bootstrap scene.
Persist Across Scenes
GameCollectionManager
Score or coin count carries between levels. Each level scene can have its own collectibles — the running total accumulates.
Persist Across Scenes
GameInventoryManager
All slot counts carry between levels. Supports up to 20 slots. Keys collected in Level1 are still in the inventory in Level2.
⚠️
Add managers to each scene that uses them
With persistence enabled, the value carries over but the manager instance is recreated per scene. This means each level scene can have its own GameCollectionManager wired to that level's collectibles — and the score accumulates correctly. This is the preferred pattern. Do not try to wire collectibles in Level2 to a manager in the bootstrap scene — cross-scene wiring doesn't work in the Inspector.

Inspector Reference

GameSceneManager fields and events

The defaults work for most games. The events let you attach transitions, progress bars, or audio cues to the load cycle.

FieldDefaultWhat it does
Use Additive LoadingtrueKeeps the bootstrap scene alive while loading the level scene on top. Recommended — leave this on.
Unload Previous ScenetrueAutomatically unloads the previous level when loading a new one. Leave on unless you need both levels loaded simultaneously.
Pre Load Delay0Seconds to wait after triggering a load before anything happens. Use this to let a fade-out animation finish before the scene changes.
Post Load Delay0Seconds to wait after loading completes before firing onSceneLoadCompleted. Use this to hold a black screen before fading in.
EventWhen it fires
onSceneLoadStartedAs soon as loading begins. Wire to a fade-out or loading screen activation.
onSceneLoadCompletedOnce the scene is fully loaded and active. Wire to a fade-in or to call CharacterControllerCC.CheckForSpawnPoint() if using additive loading with a pre-existing player.
onSceneLoadFailedIf the scene name doesn't exist in Build Settings. Wire to an error message or fallback.
onLoadProgress (float)Fires continuously during load, passing 0→1. Wire to a fill bar's SetFillAmount to show a progress bar.
MethodWhat it does
LoadScene(string)Load a scene by name. Player spawns at the default SpawnPoint.
LoadSceneAtSpawnPoint(string, string)Load a scene and spawn at a specific SpawnPoint ID. Use when entering from different doors.
LoadSceneSingle(string)Load a scene replacing all current scenes (non-additive). Use for returning to the main menu.
ReloadCurrentScene()Reload the current level scene. Wire to game-over restart logic.

SpawnPoint fields

Each level scene should have at least one SpawnPoint. Add more if the level has multiple entry points (e.g. entering from the left door vs. the right door).

FieldDefaultWhat it does
Spawn Id""Optional name for this spawn point. Set this if the level has multiple entry points and you want to choose between them using LoadSceneAtSpawnPoint().
Is Default Spawn PointtrueIf checked, this is used when LoadScene() is called with no specific ID. Only one SpawnPoint per scene should be the default.
Spawn Offset0,0,0Offset from the SpawnPoint's position. Useful for placing the spawn point on the ground while the visual marker sits at head height. A yellow line in the Scene view shows the offset.
onPlayerSpawnedFires when the player spawns here. Wire to a door-close animation or a room-reveal effect.

Common Patterns

Recipes for typical multi-scene needs