Level Blueprint vs Actor Blueprint vs Manager Actors¶
The Level Blueprint is a map script, not the default home for every gameplay idea. Put behavior where the lifetime, reuse, and audience match the job.
At a glance
Use the Level Blueprint for: one-map choreography and references to specific placed actors - Use Actor Blueprints for: reusable things with their own components, state, and behavior - Use manager actors/components/framework classes for: coordination, shared rules, or state that outgrows one placed actor - Official docs: Level Blueprint, Introduction to Blueprints, and Game Mode and Game State
The one-minute version¶
- A Level Blueprint belongs to one map. It is good for level-specific events: a one-off cutscene trigger, a placed lever opening a placed gate, streaming a sublevel from a volume, or Sequencer choreography.
- An Actor Blueprint is a reusable class. If you want three doors, ten pickups, or the same enemy in several maps, put the behavior in the actor or a component, not in the Level Blueprint.
- A placed manager actor is still an actor, but its job is coordination: wave spawner, puzzle controller, room director, music trigger, checkpoint router. It is visible in the level and can expose designer-assigned references.
- GameMode owns match rules and spawn flow. GameState owns replicated shared
runtime state. PlayerController owns local player input/UI/camera flow.
GameInstance owns runtime data that survives
Open Level. - The quick path "just put it in the Level Blueprint" is fine for a tiny one-map script. The concrete cost appears when you copy maps, need reuse, need multiplayer clients to see state, or need the logic to survive travel.
The decision table¶
| Put it here | When it is the right home | Warning sign |
|---|---|---|
| Level Blueprint | One map, one-off placed references, level streaming triggers, Sequencer/cutscene glue. | You are copying the graph into another map or searching the world every time. |
| Actor Blueprint | The thing owns the behavior: door opens itself, pickup handles pickup, projectile handles impact, enemy owns its sensors/components. | Several different actors need the same behavior and you are copy-pasting variables. |
| Actor Component | Reusable state/logic shared by different actor classes: health, inventory, team, interaction, status effects. | The component keeps reaching into unrelated actor internals instead of exposing a clean API. |
| Placed manager actor | Map-specific coordination that should be visible, assignable, testable, and reusable as a class. | It becomes a giant global object for unrelated systems. |
| GameMode | Rules for starting, spawning, restarting, scoring, pausing, and choosing default classes. | A client or widget needs to read it in multiplayer. |
| GameState | Shared runtime match state everyone needs to know: timer, score, objective phase. | It starts owning local input or private UI. |
| PlayerController | Local player input, UI ownership, camera/view target decisions, menu flow. | You put pawn-specific health, movement, or weapon state there. |
| Pawn/Character | Body-specific state: movement, health if simple, equipped weapon hooks, animation-facing data. | It must survive pawn death or be visible to all players after respawn. |
| GameInstance | Runtime values that survive full map travel: selected character, session options, temporary profile state. | You store live actor references from the old level. |
| SaveGame | Durable values that survive quitting: progress, unlocked items, settings. | You expect it to update live gameplay by itself. |
The page is not telling you to avoid the Level Blueprint forever. It is telling you to treat it as a level-specific script, not as the beginner version of a global game manager.
What each home really owns¶
Level Blueprint¶
Each level has its own Level Blueprint. It can reference actors placed in that level, bind to their events, call functions on them, and coordinate level-specific moments.
Good uses:
L_Cave Level Blueprint
-> CaveEntranceTrigger BeginOverlap
-> Play Sequencer cutscene
-> Load Stream Level "L_CaveInterior"
L_Tutorial Level Blueprint
-> PlacedButton OnPressed
-> PlacedGate Open
-> show tutorial prompt
Bad growth pattern:
L_Map01 Level Blueprint
-> all doors
-> all pickups
-> player inventory
-> enemy spawning
-> health UI
-> save/load
That graph knows too much, cannot be reused as a normal class, and will not travel cleanly into the next map.
Actor Blueprint¶
An Actor Blueprint is a class asset. Each placed or spawned instance has the same authored components, variables, functions, events, and construction logic.
Good uses:
BP_Door
BoxComponent trigger
StaticMeshComponent door panel
Timeline OpenClose
DoorState enum
OpenDoor / CloseDoor functions
Now every placed BP_Door can open itself. A level-specific trigger can still
call a specific door, but the door behavior lives with the door.
Actor Component¶
An Actor Component is reusable behavior attached to an actor. It is the better home when several unrelated actors need the same state or events.
BP_PlayerCharacter
HealthComponent
BP_Enemy
HealthComponent
BP_BreakableCrate
HealthComponent
The component owns the health math and broadcasts OnHealthChanged; each owner
decides what death means. That beats three copied health graphs.
Placed manager actor¶
A manager actor is a normal Actor Blueprint with a coordination job. The value is that it is visible in the level, can expose references in the Details panel, can be selected/debugged, and can be reused in another map.
Good uses:
BP_RoomPuzzleManager placed in L_TempleRoom
Editable references:
Levers array
Door reference
RewardSpawnPoint
On lever state changed
-> if all levers active:
Door OpenDoor
Spawn reward
The manager is better than the Level Blueprint when the coordination has a name and may be reused. It is better than GameMode when the rule is specific to a room or map area.
GameMode and GameState¶
GameMode is the rule authority for the map: default pawn class, player controller class, spawn/restart flow, pause rules, and match rules. In multiplayer, GameMode exists on the server, not on every client.
GameState is the replicated shared state for the match. If every client needs to know the match timer, score, wave number, or objective phase, GameState is usually the framework class to consider.
For single-player, you can still use these roles to keep your project organized:
GameMode:
choose player pawn
restart after death
decide current checkpoint
GameState:
optional shared state if the project may become multiplayer later
PlayerController¶
The PlayerController is the durable local player brain for many first projects. It is a good place for UI ownership, input mode changes, mouse cursor state, camera view-target switching, and menu flow.
BP_PlayerController
-> Create Widget WBP_HUD
-> bind to current pawn health component
-> open pause menu
-> Set Input Mode UI Only
-> Set Game Paused
Avoid burying UI ownership in a pawn if death/respawn replaces that pawn. The controller can rebind to the new pawn after restart.
GameInstance and SaveGame¶
GameInstance lives across full Open Level travel. Use it for runtime values
that should carry into the next map, such as selected character ID, temporary
session choices, or a loaded profile summary.
SaveGame is different. It is the durable serialized object you explicitly save to and load from a slot. GameInstance does not save itself to disk.
Do not put live actor references from the old map into either one and expect them to work after travel. Store IDs and plain values, then rebuild references in the new world.
The common quick path and its cost¶
This is acceptable:
One tutorial map
-> Level Blueprint
-> when the one placed trigger overlaps
-> play one placed Sequencer
-> open one placed door
The graph is map-specific and the project does not need reuse yet.
This is where the quick path starts costing you:
Map01 Level Blueprint:
copied door open graph
copied pickup graph
copied enemy wave graph
Map02 Level Blueprint:
pasted same graph with different actor references
Concrete costs:
- each map can drift when you fix a bug in one copy;
- copied references point to different placed actors and are easy to leave empty;
- behavior cannot be spawned as a reusable class;
- tests/debugging happen through a giant map graph instead of named objects;
Open Leveldestroys level actors and the Level Blueprint instance, so cross-map state disappears;- multiplayer clients cannot rely on server-only or non-replicated map scripts for shared state.
The stronger path is not "never use Level Blueprint." It is:
Level Blueprint:
starts the one-off level moment
BP_Door:
owns opening behavior
BP_RoomPuzzleManager:
coordinates this room's levers and door
GameMode/GameState:
own game rules and shared match state
Examples¶
Door in one tutorial map¶
Smallest acceptable version:
Level Blueprint
-> PlacedTrigger BeginOverlap
-> PlacedDoor OpenDoor
Better once doors repeat:
BP_Door
-> owns trigger, Timeline, collision changes, sounds, and DoorState
Level Blueprint
-> only starts a special cutscene or tutorial message if this map needs it
Pickup and inventory¶
Do not put pickup rules in the Level Blueprint:
BP_Pickup
-> detects overlap or receives Interact
-> sends item ID/data to InventoryComponent
-> disables/hides/destroys itself
The Level Blueprint should not know every item in the level unless the level is doing a one-off scripted sequence.
Enemy waves¶
Good first version:
BP_WaveManager placed in arena
-> SpawnPoints array
-> EnemyClasses array
-> CurrentWave
-> OnEnemyDied
-> starts next wave
If the wave rules become match-wide, move the rule owner toward GameMode and replicate shared wave state through GameState.
Pause menu¶
Prefer PlayerController:
BP_PlayerController
-> input Pause
-> create/show menu
-> Set Game Paused
-> Set Input Mode UI Only
-> restore on close
Putting this in a Level Blueprint makes it map-specific and awkward to reuse. Putting it in a pawn makes respawn and possession changes more fragile.
Failure patterns¶
| Symptom | Likely ownership problem |
|---|---|
| A system works in one map but not another | Logic lives in one Level Blueprint instead of a reusable actor/component/framework class. |
Door variable is typed BP_Door but empty |
A variable type is not an assignment; the Level Blueprint or actor instance still needs a reference. |
| Inventory disappears after changing maps | It lived in a level actor or pawn that Open Level destroyed. |
| UI breaks after respawn | Widget ownership or bindings lived on the old pawn instead of the controller/HUD path. |
| Multiplayer client cannot find GameMode | GameMode is server-side; shared client-readable state belongs in GameState/PlayerState or replicated actors. |
| Copied level script opens the wrong object | A pasted placed-actor reference still points to the old map's assumption or is unassigned. |
| Manager actor becomes untestable | It owns unrelated global systems instead of one named coordination job. |
Get Actor Of Class appears everywhere |
References are not being passed, assigned, spawned, or exposed at the right ownership boundary. |
What the Level Blueprint does not do¶
- It does not create reusable gameplay classes.
- It does not survive full
Open Leveltravel. - It does not automatically replicate its variables to clients.
- It does not replace GameMode, GameState, PlayerController, Pawn, GameInstance, or SaveGame.
- It does not make a typed variable find an actor instance.
- It does not make copied map scripts stay in sync.
- It does not make spawned actors know about placed references unless you pass or assign them.
A practical rule for first projects¶
Ask three questions before placing the graph:
- Whose lifetime is this? If the state should die with a projectile, put it
in the projectile. If it should survive pawn death, do not put it only in the
pawn. If it should survive
Open Level, do not put it in the level. - Will I need another copy? If yes, make an Actor Blueprint, component, or manager class instead of Level Blueprint script.
- Who needs to read it? If clients need it in multiplayer, do not hide it in server-only GameMode or private local UI. Use replicated gameplay state.
For tiny one-map choreography, use the Level Blueprint. For anything reusable, put the behavior on the actor/component that owns it. For coordination, give the coordination a named manager or framework owner.
Going deeper¶
- GameMode & friends, single-player edition - default classes, spawn flow, GameMode, GameState, PlayerController, Pawn, and HUD roles.
- Game Instance - runtime data that survives
Open Level. - Actor Components as reusable gameplay - reusable state such as health, inventory, team, and interaction.
- Actor, Scene, and Primitive Components - when behavior belongs in an actor part instead of the map.
- Blueprint variables and references - why a variable type is not an assigned instance.
- Construction Script vs BeginPlay - editor-time setup vs runtime gameplay start.
- Open Level - full travel destroys level actors and starts a new map world.
- Level streaming basics - map-specific streaming coordination that often starts from triggers or Level Blueprint glue.
- Event Dispatchers - manager/listener patterns without constant world searches.
- Get Actor Of Class / Get All Actors Of Class - why repeated searching is usually a sign that ownership/reference passing is missing.
- Multiplayer roles and Replication basics - which machines have which framework objects and where shared state belongs.
- Official docs: Level Blueprint, Introduction to Blueprints, Blueprint Class Assets, Actors, Components, and Game Mode and Game State.
- Engine source (requires engine access - we do not reproduce it here):
Level Blueprint runtime actor behavior in
ALevelScriptActordeclarations atEngine/Source/Runtime/Engine/Classes/Engine/LevelScriptActor.hand implementation inEngine/Source/Runtime/Engine/Private/LevelScriptActor.cpp; actor lifecycle inAActor::BeginPlay,AActor::EndPlay, and related functions inEngine/Source/Runtime/Engine/Private/Actor.cpp; spawn/restart rule ownership inAGameModeBasefunctions inEngine/Source/Runtime/Engine/Private/GameModeBase.cpp; cross-map runtime object setup inUGameInstancefunctions inEngine/Source/Runtime/Engine/Private/GameInstance.cpp.