Skip to content

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 be None.
  • 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_Door does 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.
  • SaveGame is for plain durable data copied into a SaveGame object. Do not expect actor references to survive Open Level or 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_Door actor 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:

  1. Never assigned. The variable type was set, but no BeginPlay, spawn pin, overlap, trace, or Details-panel assignment ever provided a value.
  2. Wrong instance. You assigned the class default but are reading a placed instance, or you are debugging one copy while another copy is running.
  3. Assigned too late. The variable is read in Construction Script, but the value is only assigned at BeginPlay.
  4. World changed. Open Level destroyed the actors from the old map.
  5. 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