Level streaming basics¶
Level streaming keeps the current world running while you load or unload sublevels. It is not the same thing as Open Level.
The one-minute version¶
- Open Level leaves the current map and loads another map as the active world. Normal actors in the old world are torn down.
- Level streaming starts with a persistent level - the master level that stays loaded - plus streaming levels or sublevels that can appear and disappear inside that world.
Load Stream Levelrequests a sublevel be loaded.Unload Stream Levelrequests that a loaded sublevel be removed again.Make Visible After Loadmeans the level becomes visible/active after it is loaded.Should Block on Loadmeans the game can pause waiting for the load; most first projects leave blocking off.- Streaming is for interiors, elevators, hub chunks, large buildings, and seamless transitions. It is usually not needed for "main menu to gameplay" or "level complete to next independent map."
- UE5 also has World Partition for large-world streaming. This page is the beginner Blueprint mental model for manual level streaming and sublevels.
Open Level vs level streaming¶
The shortest split:
Open Level
-> replace the current world with another map
Load Stream Level
-> keep the persistent world
-> load a sublevel into it
That lifetime difference is the whole reason to use streaming.
| Need | Use | Why |
|---|---|---|
| Main menu to gameplay map | Open Level | You want a different map/world setup. |
| Restart this map | Open Level | You want a fresh world. |
| Door opens to an interior that shares the same outdoor world | Level streaming | The outdoor world keeps running while the interior loads. |
| Elevator hides loading between two nearby areas | Level streaming | You can keep the persistent actors and UI alive. |
| Huge open-world terrain | World Partition or advanced streaming | Manual sublevels may be the wrong scale. |
The quick path is to use Open Level for every transition. The concrete cost
is that any actor state in the current world disappears, so you end up
rebuilding persistent managers, UI references, doors, and music that streaming
would have kept.
The pieces¶
flowchart TD
P[Persistent Level<br/>always the loaded world] --> A[Sublevel: ExteriorChunk_A]
P --> B[Sublevel: ShopInterior]
P --> C[Sublevel: DungeonEntrance]
Trigger[Door / volume / script in persistent level] --> Load[Load Stream Level]
Load --> B
Persistent level¶
The persistent level is the master level. Put long-lived level logic here:
- player start and core player path, when appropriate;
- streaming trigger actors or volumes;
- global lighting/skies/post-process that should always be present;
- managers that should stay alive while sublevels come and go.
Do not put a door trigger inside the sublevel that must be loaded by that same door. If the sublevel is not loaded yet, its trigger is not there to run.
Streaming levels / sublevels¶
Sublevels hold pieces of the world that can be loaded or unloaded:
- an interior room;
- an area beyond a door;
- a visual layer such as lighting or art split for collaboration;
- a chunk that should not take memory until the player approaches it.
When a streamed sublevel is unloaded, actors in that sublevel go away. The persistent level remains.
Always Loaded vs Blueprint¶
In the Levels window, a sublevel can be set up as always loaded or controlled by Blueprint/streaming logic.
| Setting | Beginner meaning |
|---|---|
| Always Loaded | Loaded with the persistent level and not controlled by Load/Unload Stream Level during play. Useful for art/team layers or content that should always exist. |
| Blueprint | Can be loaded/unloaded by Blueprint nodes, C++ code, or streaming volumes. Use this for first manual streaming setups. |
If Load Stream Level appears to do nothing, confirm the sublevel is actually
configured for Blueprint streaming and that the name/reference matches.
The Blueprint pattern¶
The common first pattern is a trigger in the persistent level:
Box BeginOverlap
-> filter Other Actor == player
-> Load Stream Level
Level Name = "L_ShopInterior"
Make Visible After Load = true
Should Block on Load = false
Then unload later:
Box EndOverlap or exit trigger
-> filter Other Actor == player
-> Unload Stream Level
Level Name = "L_ShopInterior"
Should Block on Unload = false
Many real games load earlier than the door and unload later than the exit. The beginner version above is useful because it proves the mechanics.
What the Load pins mean¶
| Pin | Meaning |
|---|---|
| Level Name / Level | The sublevel to stream. Use the actual level package/asset reference, not a display label. |
| Make Visible After Load | If true, the sublevel becomes visible after loading. If false, it can be loaded in memory but hidden until you show it. |
| Should Block on Load | If true, the game waits for the load to finish before continuing. That can cause a hitch; leave false for normal streaming tests. |
| Completed | The latent output that fires after the load/unload request completes. Use it for follow-up logic that really must wait. |
Load Stream Level has no success boolean. The API docs note that calling it
again while the same level is still loading has no effect. Failure usually
looks like a log warning, no visible level, or a Completed path that does not
produce the world state you expected.
What survives streaming?¶
| Thing | Survives loading/unloading a sublevel? | Beginner note |
|---|---|---|
| Persistent-level actors | Yes | They stay while sublevels come and go. |
| PlayerController / possessed pawn | Usually yes | You are not replacing the whole world. |
| Widgets created by the player UI path | Usually yes | They belong to the local player path, not the streamed sublevel. |
| Actors inside the loaded sublevel | Only while that sublevel is loaded | Unload removes that area's actors. |
| References to sublevel actors | Become stale after unload | Guard or reacquire them after load. |
| GameMode / GameState | Yes for the persistent world | Unlike Open Level, you are not creating a new map's framework setup. |
| SaveGame data | Not automatic | Streaming is not disk saving. |
This is why streaming is useful for a hub: the player, HUD, and persistent world stay alive while a shop interior appears and disappears.
When first projects actually need it¶
Good first uses:
- an interior behind a door where the outside world should stay loaded;
- an elevator or hallway that hides a streamed-in area;
- a hub with optional rooms;
- a large level split so memory/editor collaboration is manageable;
- ambience or art layers that should load independently.
Usually unnecessary:
- main menu to game map;
- restarting the current level;
- going from Level 1 to completely separate Level 2;
- one small room that already runs fine;
- fixing bad references that should instead be owned correctly.
Streaming adds setup overhead. Use it when keeping the persistent world alive solves a real problem.
Streaming volumes¶
Level Streaming Volumes can load/unload levels based on the player's viewpoint entering or leaving volumes. They are useful when distance or area boundaries should drive streaming without a custom Blueprint script.
Important beginner constraints:
- streaming volumes belong in the persistent level;
- volume setup can fight manual Blueprint streaming if both try to control the same level;
- resizing the volume changes how early the level loads and how late it unloads.
If your first goal is a scripted door, start with Blueprint Load Stream Level.
If the goal is area-based loading around the player, a streaming volume may be
cleaner.
Common traps¶
- Using Open Level when you meant streaming. Your persistent actors vanish because you loaded a new world.
- Using streaming when you meant Open Level. You keep old state that should have reset.
- Wrong level name. The node needs the sublevel package/asset name it can resolve.
- The sublevel is Always Loaded. Load/Unload requests do not control it the way a Blueprint-streamed sublevel is controlled.
- The trigger lives in the unloaded sublevel. It cannot fire before the level exists.
- Blocking load causes a hitch. Leave
Should Block on Loadfalse until you have a specific reason. - You stored references to sublevel actors. Those actors can be destroyed on unload; reacquire after load or store plain state elsewhere.
- Packaged build missing the sublevel. Test packaged streaming paths before assuming an editor-only success proves shipping setup.
Multiplayer note¶
Streaming has networking details once clients join. The server still owns authoritative gameplay state, and clients need compatible level assets and visibility state for replicated actors to make sense.
For a beginner multiplayer project, do not treat streaming as a way to hide authority problems. First understand multiplayer roles and replication basics, then decide how streamed areas are controlled in your game.
Going deeper¶
- Open Level - the full-map travel node that streaming is usually compared against.
- Game Instance - runtime data that survives Open Level; often less necessary for data that can stay in the persistent world.
- World vs relative transforms - useful when streamed sublevels and attached/offset content make coordinates confusing.
- Spawn Actor from Class - spawning actors after a streamed level appears.
- Official docs: Level Streaming Overview, Loading and Unloading Levels using Blueprints, Level Streaming Volumes Reference, Managing Multiple Levels, UGameplayStatics, and ULevelStreaming.
- Engine source (requires engine access - we do not reproduce it here):
UGameplayStatics::LoadStreamLevel,UGameplayStatics::LoadStreamLevelBySoftObjectPtr,UGameplayStatics::UnloadStreamLevel, andUGameplayStatics::UnloadStreamLevelBySoftObjectPtrare declared inEngine/Source/Runtime/Engine/Classes/Kismet/GameplayStatics.hand implemented inEngine/Source/Runtime/Engine/Private/GameplayStatics.cpp; streaming level state is represented byULevelStreaminginEngine/Source/Runtime/Engine/Classes/Engine/LevelStreaming.h.