Blueprint variables and references¶
A variable is a named slot on a Blueprint instance. Sometimes the slot holds a plain value. Sometimes it holds a pointer to another Unreal object. The type does not go looking for the object for you.
The one-minute version¶
- A value variable stores data directly:
Boolean,Integer,Float,Vector,Rotator,Transform,Name,String,Text, structs, enums, and similar plain data. - An object reference stores a reference to one specific live object, such
as a placed
BP_Door, a spawned projectile, a widget instance, or a component. It can beNone. - A class reference stores a class choice, such as "spawn this kind of projectile." It is not an instance in the world.
- An asset reference points at content, such as a texture, sound, montage, data asset, or soft asset path. It is not the same as a live actor reference.
- Setting a variable's type to
BP_Doordoes not search the level for a door. It only says what kind of object the variable may hold after something assigns it. - Mark a variable Instance Editable when each placed copy needs a designer value. Mark it Expose on Spawn when the spawner must provide a value before Construction Script setup finishes.
SaveGameis for plain durable data copied into a SaveGame object. Do not expect actor references to surviveOpen Levelor quitting.
Value vs reference¶
The beginner bug usually starts with this sentence:
"I made a variable of type
BP_Door, so why is it empty?"
Because the type is only a rule for what the slot can hold. It is not an assignment.
Variable: Health
Type: Float
Value stored directly: 75.0
Variable: CurrentDoor
Type: BP_Door Object Reference
Value stored indirectly: a pointer to one live BP_Door instance, or None
A value variable is a copy of data. If you set Health from 75 to 50, the
number changes right there on that Blueprint instance.
An object reference is an address to another object managed by Unreal. If
CurrentDoor points at a door and you call OpenDoor on it, you are talking
to that door instance. If the variable is None, there is no target for the
call and you will usually see
Accessed None when your graph tries to read through it.
The common reference types¶
| Type | Holds | Use when |
|---|---|---|
| Object reference | One object instance, or None |
You already have the actor, component, widget, controller, or asset loaded and want to talk to it. |
| Actor reference | One live actor in a world, or None |
A placed door, spawned pickup, current target, or owning character. |
| Component reference | One component on an actor, or None |
A mesh, trigger box, audio component, health component, or camera component. |
| Class reference | A class/type, not an instance | Spawn Actor from Class, Create Widget, Add Component by Class, or choosing which enemy type to create. |
| Asset reference | Content data, usually not a live world object | Sound, texture, material, montage, data asset, data table, or Blueprint class asset. |
| Soft reference | A path-like reference that may not be loaded yet | Large optional content, menu thumbnails, or advanced streaming/loading patterns. |
Blueprint's object pins often show a broad declared type. A variable declared
as Actor can hold a BP_Door because BP_Door is an Actor subclass. A
variable declared as BP_Door cannot hold a random BP_Enemy because that is
not the promised type. The broader-vs-specific rule is the same one behind
Cast To X and the
gameplay class hierarchy.
Why a typed variable does not find anything¶
Unreal does not search the world just because a variable has an object type. That would be ambiguous and expensive:
Variable Type = BP_Door Object Reference
Unreal still does not know:
- which of ten placed BP_Door instances you meant;
- whether the door is in the current level, a streamed level, or another map;
- whether the value should be assigned at design time, on overlap, by a trace,
by the spawner, or by the door itself broadcasting an event.
You must choose the assignment path:
| Situation | Assignment pattern |
|---|---|
| Placed switch controls a placed door | Make TargetDoor Instance Editable on the switch, then pick the door instance in the Details panel. |
| Spawned projectile needs its damage owner | Mark InstigatorPawn or DamageAmount Expose on Spawn and pass it through Spawn Actor from Class. |
| Player looks at an interactable object | Use Line Trace By Channel, then store or call the hit actor. |
| Trigger tracks who is inside | Add on BeginOverlap, remove on EndOverlap, usually with an array or set. |
| Widget needs the current character | Create/store the widget from the PlayerController or HUD path, then pass the character reference into it. |
| Object may not exist yet | Store a class, asset, tag, ID, or SaveGame value, then resolve to a live reference later. |
Get Actor Of Class can be useful for quick debugging, but it is not a hidden
assignment system. If your design depends on "find some door somewhere," the
reference ownership is probably unclear.
Instance Editable, Expose on Spawn, SaveGame¶
These checkboxes answer different timing questions.
Instance Editable¶
Use Instance Editable when a value belongs to a placed copy of the Blueprint.
Example:
BP_Switch placed in Level_A
TargetDoor = BP_Door_03
RequiredKeyId = "Storage"
Each placed switch can point at a different door. The value exists because a designer picked it on that instance. It is not copied to every switch unless you set the class default that way.
Use this for placed-level wiring, tuning numbers, references to other placed actors, and values a level designer should see in Details.
Expose on Spawn¶
Use Expose on Spawn when the value must be provided while a new object is being created.
Spawn Actor from Class BP_Projectile
-> DamageAmount = 25
-> InstigatorPawn = Self
For spawned actors, exposed pins are available on Spawn Actor from Class. For widgets, the same idea appears on create-widget flows. The important timing is that the new object can read the value during its initial setup instead of waiting for the caller to set it afterward.
SaveGame¶
SaveGame marks data that may be serialized when you copy values into a
SaveGame object and call
Save Game to Slot. It is
not "autosave this variable from every actor."
Good SaveGame values:
- player level, unlocked doors by ID, inventory item IDs/counts;
- checkpoint ID, map name, health number;
- plain structs/enums/numbers/text that you can rebuild from.
Bad SaveGame values:
BP_Dooractor references from the old world;- widget references;
- controller, pawn, component, or animation instance references.
After Open Level, rebuild live references in the new world from IDs, tags,
placed actors, or spawn results.
When references are empty or stale¶
Object references can be None because nothing assigned them. They can also
become invalid because the object they pointed at was destroyed, removed from
the world, or belonged to a level that was unloaded.
Common cases:
- Never assigned. The variable type was set, but no BeginPlay, spawn pin, overlap, trace, or Details-panel assignment ever provided a value.
- Wrong instance. You assigned the class default but are reading a placed instance, or you are debugging one copy while another copy is running.
- Assigned too late. The variable is read in Construction Script, but the value is only assigned at BeginPlay.
- World changed.
Open Leveldestroyed the actors from the old map. - Object was destroyed. The variable still looks like a reference slot, but Is Valid says the object should not be used.
Failure is not an exception. Unreal gameplay code keeps executing through your graph. The failure appears when you use the empty reference: the call is skipped or an Accessed None warning points at the read node.
The pattern everyone actually uses¶
For a placed door switch:
BP_DoorSwitch variable:
TargetDoor (BP_Door Object Reference)
Instance Editable = true
Level designer:
select placed switch
set TargetDoor to placed BP_Door_03
Interact event:
Is Valid TargetDoor
-> TargetDoor.OpenDoor()
For a spawned projectile:
BP_Projectile variables:
DamageAmount (Float, Expose on Spawn)
InstigatorPawn (Pawn Object Reference, Expose on Spawn)
Character Fire:
Spawn Actor from Class BP_Projectile
-> pass DamageAmount and InstigatorPawn
For durable progress:
Door opens
-> add DoorId to OpenDoorIds array in SaveGame data
-> Save Game to Slot
New map loads
-> Load Game from Slot
-> for each placed door:
if OpenDoorIds contains DoorId:
set door open
Lookalikes - which one do I want?¶
| Need | Use | Avoid |
|---|---|---|
| Store a number, bool, vector, enum, or struct | Value variable | Object reference, unless there is an actual object. |
| Talk to one live actor/component/widget | Object reference | Class reference; a class cannot receive instance calls. |
| Choose what to spawn later | Class reference | Placed actor reference. |
| Reference content/tuning data | Asset or data asset reference | Live actor reference from a map. |
| Save progress across sessions | SaveGame data with IDs/plain values | Actor/component/widget references. |
| Let a placed instance choose a target | Instance Editable object reference | Get Actor Of Class on Tick. |
| Pass setup data into a newly spawned object | Expose on Spawn | Setting after spawn when Construction Script needed it. |
Rule of thumb: type answers "what can this hold?" Assignment answers "what does it hold right now?" Bugs happen when those two questions get blurred.
Going deeper¶
- Accessed None trying to read property - how empty references fail in Blueprint.
- Is Valid - the guard for optional or destroyable object references.
- Spawn Actor from Class - where Expose on Spawn values become pins.
- Open Level and Game Instance
- why level travel destroys live actors but not plain runtime data in the GameInstance.
- Save Game: Create / Save / Load Game to Slot
- durable data is copied in and out manually.
- Official docs: Blueprint Variables, Blueprint Variable Properties, and Spawn Actor from Class.
- Engine source (requires engine access - we do not reproduce it here):
variable get/set Blueprint nodes in
Engine/Source/Editor/BlueprintGraph/Private/K2Node_VariableGet.cppandEngine/Source/Editor/BlueprintGraph/Private/K2Node_VariableSet.cpp; Blueprint compilation and reflected properties inEngine/Source/Editor/KismetCompiler/andFPropertydeclarations underEngine/Source/Runtime/CoreUObject/Public/UObject/UnrealType.h.