Load Stream Level / Unload Stream Level¶
At a glance
Lives in: Blueprint API / Game; implemented by Gameplay Statics -
Returns: no loaded-level object in Blueprint; the latent Completed
pin fires when the stream request finishes - Fails by: doing nothing
useful, never showing the level you expected, or completing with an invalid
setup you still need to debug - Official docs:
Load Stream Level,
Loading and Unloading Levels using Blueprints,
Level Streaming Overview,
and UGameplayStatics
The one-minute version¶
Load Stream Levelrequests a sublevel to be loaded into the current persistent world. It is a latent node: the graph continues fromCompletedlater.Make Visible After Loadmeans "show the streamed level once it is loaded." Loaded and visible are separate states.Unload Stream Levelrequests a streamed level to be removed from the world.- Calling load again while the same latent load is already pending does not stack a second useful load.
- These nodes are not
Open Level. Streaming keeps the persistent world alive;Open Leveltravels to another map and destroys the old world actors. - Level streaming does not save actor state for you, replicate a gameplay rule by itself, or make direct references to actors in unloaded sublevels safe.
What they actually do¶
Streaming works inside a persistent level:
flowchart LR
P[Persistent Level] --> A[Always present actors]
P --> S1[Streamed sublevel: L_Interior]
P --> S2[Streamed sublevel: L_Basement]
Load Stream Level asks the world to load a named sublevel package and, if
requested, make it visible. Unload Stream Level asks the world to hide/remove
that streamed level.
pseudocode of the engine behavior - not engine source
function LoadStreamLevel(LevelName, MakeVisible, ShouldBlock, LatentInfo):
StreamingLevel = find streaming level by package/name
if StreamingLevel is None:
finish latent action without a useful loaded level
return
if this load request is already pending:
keep the existing request
return
StreamingLevel.ShouldBeLoaded = true
StreamingLevel.ShouldBeVisible = MakeVisible
wait until streaming update completes
fire Completed
function UnloadStreamLevel(LevelName, ShouldBlockOnUnload, LatentInfo):
StreamingLevel = find streaming level by package/name
if StreamingLevel is None:
finish without removing anything useful
return
StreamingLevel.ShouldBeLoaded = false
StreamingLevel.ShouldBeVisible = false
wait until streaming update completes
fire Completed
For the bigger model, read Level streaming basics.
When it fails (and what failure does)¶
Failure often looks like "nothing changed" rather than a Blueprint error.
Common causes:
- The level name is wrong. Use the package/sublevel name Unreal expects, not a display label you invented in the graph.
- The level is not configured as a streamed sublevel. A normal map name
for
Open Levelis not automatically available as a streaming level in the current persistent world. - You loaded but did not make it visible. Loaded data can exist without being rendered or active the way a beginner expects.
- You already have the same request in flight. Repeated calls before the first finishes do not create a queue of duplicate loads.
- You kept direct references to actors that are not loaded anymore. Actors in unloaded sublevels can be destroyed or unavailable; use managers, IDs, soft references, or rebinding after load.
- Blocking flags caused a hitch. Blocking load/unload can stall play while the work is completed.
- Multiplayer state is underspecified. Streaming level visibility and gameplay authority are separate. Decide whether the server, each client, or local presentation owns the request.
There is no returned Level object to validate from the basic Blueprint node.
Use prints, Get Streaming Level, PIE logs, and the Levels window to prove
which level is loaded and visible.
The pattern everyone actually uses¶
For a doorway/interior:
Persistent-level trigger BeginOverlap
-> filter player
-> Load Stream Level("L_ShopInterior",
Make Visible After Load = true,
Should Block on Load = false)
-> Completed
-> enable shop interaction / fade out loading prompt
Trigger EndOverlap or exit event
-> Unload Stream Level("L_ShopInterior",
Should Block on Unload = false)
For a first project, keep the trigger/manager in the persistent level, not inside the sublevel that may unload itself.
The C++ twin, for the curious (our own example code):
void ALevelDoorway::RequestInteriorLoad()
{
FLatentActionInfo LatentInfo;
LatentInfo.CallbackTarget = this;
LatentInfo.ExecutionFunction = FName("OnInteriorLoaded");
LatentInfo.Linkage = 0;
LatentInfo.UUID = 1;
UGameplayStatics::LoadStreamLevel(
this, FName("L_ShopInterior"), true, false, LatentInfo);
}
Streaming state is not save state¶
Loading a sublevel is a runtime visibility/memory choice. It does not mean:
- actors in that sublevel keep custom state after being unloaded,
- SaveGame data is written,
- every client has made the same visibility choice,
- old references from before unload are safe.
If a chest in a streamed room should stay opened, store a durable ID/value in a manager, GameInstance, replicated state, or SaveGame, then apply it when the level loads again.
Lookalikes - which one do I want?¶
| Node / system | Changes | Use when |
|---|---|---|
| Load Stream Level | Loads a sublevel into the current persistent world | You want an area to appear without full map travel. |
| Unload Stream Level | Removes a streamed sublevel | You want to free/hide an area while keeping the persistent world. |
| Get Streaming Level | Returns the streaming-level object, or None |
You need to inspect or change a streaming level directly. |
| Open Level | Travels to another map/world | You want a full map change and old world actors should be replaced. |
| Level Streaming Volumes | Editor-driven stream triggers | Loading should be driven by player location and volume setup. |
| World Partition | Large-world streaming system | You are building large spatial worlds beyond beginner sublevel setup. |
| SaveGame | Disk-backed durable data | State must survive quitting or relaunching. |
Rule of thumb: Use streaming to keep the current world and swap pieces of it; use Open Level to leave the world; use SaveGame to keep data outside the world.
Going deeper¶
- Level streaming basics - persistent levels, streamed sublevels, and beginner setup.
- Open Level - full map travel and what gets destroyed.
- Game Instance - runtime values that survive full level travel on the same process.
- Does Save Game Exist / Delete Game in Slot / Async Save Game to Slot
- durable save-slot utilities.
- On Component Begin / End Overlap
- common trigger shape for load/unload volumes.
- Official docs: Loading and Unloading Levels using Blueprints, Level Streaming Overview, and UGameplayStatics.
- Engine source (requires engine access - we do not reproduce it here):
UGameplayStatics::LoadStreamLevel,UGameplayStatics::LoadStreamLevelBySoftObjectPtr,UGameplayStatics::UnloadStreamLevel, andUGameplayStatics::GetStreamingLevelinEngine/Source/Runtime/Engine/Private/GameplayStatics.cpp; streaming-level classes underEngine/Source/Runtime/Engine/Private/LevelStreaming.cpp.