Get Instigator / Get Instigator Controller¶
At a glance
Lives in: Blueprint API / Game - Target: an Actor (normally
self inside that Actor) - Get Instigator returns: the Pawn credited as
the Actor's instigator, or None - Get Instigator Controller returns:
that Pawn's current Controller, or None - Changes state: no; both are
pure reads - Official docs: Get
Instigator
and Get Instigator
Controller
An Actor's Instigator answers "which Pawn caused or initiated this Actor?" It is most useful on spawned projectiles, temporary damage volumes, traps, and other Actors that need to remember the responsible Pawn.
The word does not mean Owner, the Actor itself, or whoever last touched it.
Instigator is one explicit Actor property. If nothing assigned that property,
both getters can validly return None.
The one-minute version¶
Get Instigatorreturns the Actor's storedPawnreference.Get Instigator Controllerfirst gets that Pawn, then asks for its current Controller. It is a live lookup, not a Controller snapshot saved when the Actor spawned.- The declared Instigator type is
Pawn. A Character is valid because Character derives from Pawn. - The most reliable setup is to pass Instigator on the authoritative
Spawn Actor from Classcall. The spawned Actor can then read it during its normal gameplay lifetime. - A Pawn can be unpossessed, repossessed, or destroyed. The Instigator
reference may therefore exist while the Controller getter returns
None, or the controller result may differ from the one present at spawn time. - The Instigator property is replicated as part of a replicated Actor when assigned by the server, but the controller result is not a separately replicated snapshot.
- AIControllers normally exist only on the server. A client can know the instigator Pawn and still be unable to resolve its AIController.
- Use the instigator to help with attribution and self-filtering, but let the server validate damage and other authoritative outcomes. A client-provided reference is not proof of responsibility.
- If credit must survive possession changes, disconnection, or Pawn destruction, snapshot a stable identity such as PlayerState, team ID, or another project-owned attribution record at spawn time.
The actual relationship¶
Conceptually, the two getters follow this chain:
Actor
`-- Instigator property ------> Pawn
`-- current Controller ------> Controller
The behavior is roughly:
pseudocode - not engine source
GetInstigator(Actor):
return Actor.StoredInstigatorPawn
GetInstigatorController(Actor):
Pawn = Actor.StoredInstigatorPawn
if Pawn is invalid:
return None
return Pawn.GetController()
That distinction matters:
| Situation | Get Instigator | Get Instigator Controller |
|---|---|---|
| No instigator was assigned | None |
None |
| Instigator Pawn exists and is possessed | Pawn | its current Controller |
| Instigator Pawn exists but is unpossessed | Pawn | None |
| Same Pawn was repossessed by another Controller | same Pawn | new current Controller |
| Instigator reference has become invalid | invalid/None-shaped reference |
None |
| Client knows an AI Pawn but has no AIController there | Pawn may be valid | commonly None |
Neither node creates a missing relationship, searches the world for a likely shooter, or repairs an invalid reference.
Why the node may not appear from another Actor reference¶
Both Blueprint getters are marked BlueprintProtected. In ordinary Blueprint
use, they are intended to be called from inside the Actor whose Instigator is
being read:
inside BP_Projectile
-> Get Instigator (Target = self)
-> Get Instigator Controller (Target = self)
If you drag from an arbitrary Actor reference in another Blueprint, the context-sensitive menu may therefore not offer these nodes even though their native target class is Actor. That is an access rule, not evidence that the other object cannot have an Instigator.
Keep attribution handling inside the projectile/damage Actor when practical.
If another Blueprint genuinely needs the result, expose a narrow public
function or interface on that Actor that returns the project-level
attribution it is allowed to reveal. Native C++ can call the public
AActor::GetInstigator() and GetInstigatorController() functions on an
Actor pointer directly.
What the Instigator property stores¶
AActor::Instigator is declared as a Pawn reference. It is exposed on spawn
and is replicated with an OnRep_Instigator notification.
Pawn is the declared type¶
The return pin says Pawn, so it can carry:
- a plain Pawn;
- a Character, because Character is a Pawn subclass;
- a vehicle or creature Pawn implemented by the project.
It does not directly carry a PlayerController, PlayerState, weapon, component, or generic Actor. Get the related object deliberately after validating the Pawn.
Get Instigator
-> Is Valid?
-> Cast to BP_PlayerCharacter only if this system truly requires that class
Do not cast merely to test whether an instigator exists. A base Pawn reference is already sufficient for comparisons, team interfaces, and many damage contracts.
The value is assigned, not inferred¶
Unreal does not automatically choose "the nearest player" or "the Actor's Owner" as Instigator. Common assignment points are:
- the
Instigatoradvanced pin onSpawn Actor from Class; - an engine or project spawn path that fills the native spawn parameters;
- an intentional write to the Actor's Instigator property in C++ or Blueprint where that property is exposed.
If a projectile was placed in the level or spawned without the pin, Get
Instigator returning None is expected. The getter cannot infer who should
receive credit.
Spawn it with the attribution already present¶
For a projectile, the clean flow is:
server-owned weapon or firing Pawn
-> Spawn Actor from Class
Class = BP_Projectile
Transform = muzzle transform
Owner = weapon or owning Actor, if the ownership design needs it
Instigator = firing Pawn
-> projectile BeginPlay / overlap / hit can read Get Instigator
The spawn system transfers the Instigator from its spawn parameters during the Actor's spawn initialization. That means a correctly supplied value is available to the spawned Actor's normal construction and BeginPlay flow; it is not a later best-effort lookup.
Passing the reference on the spawn call is usually better than:
Spawn Actor
-> later call a custom "Set Shooter" event
The later event creates a window where BeginPlay or an immediate collision can run before attribution is set. A separate variable is still appropriate when the project needs a richer attribution record than the built-in Pawn link.
If deferred spawning is used in C++, finish all intended spawn-time setup before completing the spawn. Do not treat a partially constructed Actor as a normal gameplay Actor.
Get Instigator Controller is a live lookup¶
The Controller is not stored beside the Pawn as historical credit. The getter asks the Instigator Pawn which Controller possesses it now.
Consider a projectile that remains alive for ten seconds:
time 0: Pawn_A is possessed by PlayerController_A
projectile stores Instigator = Pawn_A
time 4: PlayerController_A unpossesses Pawn_A
time 6: Controller_B possesses Pawn_A
time 8: projectile calls Get Instigator Controller
result = Controller_B
If the requirement is "who controlled the Pawn when this shot was fired," the live controller getter is the wrong historical record. Capture the needed stable identity at spawn time.
This is especially important for:
- delayed explosions;
- damage-over-time Actors;
- mines or traps that persist after their creator dies;
- vehicles whose driver can change;
- players who respawn into a new Pawn;
- disconnect/reconnect and team-change flows.
None is part of the contract¶
Both outputs require validity handling when their absence changes behavior.
Instigator Pawn = Get Instigator
-> Is Valid
true: use Pawn for exclusion or attribution
false: use explicit environment/world-damage policy
Common reasons include:
- The Actor was spawned without an Instigator.
- The Actor was placed in a level rather than caused by a Pawn.
- A non-Pawn system created it and did not choose a responsible Pawn.
- The stored Pawn has been destroyed or is no longer available.
- The Pawn exists but currently has no Controller.
- The graph is running on a client where that Controller does not exist.
- The call runs too early or on a different Actor than intended.
Do not convert None silently into "the local player." That can award
environmental or server damage to whichever client happens to execute the
graph.
The projectile self-filter pattern¶
Instigator is useful for avoiding a projectile damaging the Pawn that fired it:
On Component Hit / Begin Overlap
-> Other Actor
-> compare with Get Instigator
-> if equal:
ignore this damage path
else:
continue with authoritative hit validation
Validate the Instigator before relying on the comparison. Then use it as the event instigator when applying damage:
InstigatorController = Get Instigator Controller
Apply Point Damage
Damaged Actor = validated hit Actor
Event Instigator = InstigatorController
Damage Causer = self (the projectile)
This records two different facts:
- Event Instigator: the responsible Controller, if one is available;
- Damage Causer: the Actor that physically caused this damage event.
Instigator-based comparison is not a replacement for collision setup. A projectile can still collide with its firing Pawn, generate hit/overlap work, or bounce from it before the graph decides not to apply damage. Also consider:
- ignoring the firing Actor when configuring the trace or movement collision;
- collision channels/profiles that exclude the projectile owner group;
Move Ignore Actorsor the equivalent project-specific ignore list;- spawn placement that does not begin inside the firing Pawn.
Use both physical filtering and gameplay validation when the design needs both.
The names people confuse¶
| Name | What it means | Typical projectile value |
|---|---|---|
| self | The Actor running this graph | the projectile |
| Instigator | Pawn credited as initiating this Actor | firing Pawn |
| Instigator Controller | That Pawn's current Controller | firing PlayerController or AIController, if available here |
| Owner | A separate Actor ownership link used by gameplay and networking rules | weapon, firing Pawn, Controller, or another project choice |
| Event Instigator | Controller supplied to a damage event | usually the validated responsible Controller |
| Damage Causer | Actor supplied as the immediate cause of damage | projectile, weapon, explosion Actor |
| Attachment Parent | Scene hierarchy parent of the Actor/component | muzzle, weapon, vehicle, or none |
| Owning connection | Network connection allowed to own relevant Actors/RPC paths | derived through network ownership, not Instigator |
These references may point into the same gameplay chain, but they are not aliases and Unreal does not keep them synchronized for you.
For example:
PlayerController
`-- possesses Character Pawn
`-- owns/equips Weapon Actor
`-- spawns Projectile Actor
Projectile self = Projectile
Projectile Instigator = Character Pawn
Projectile Owner = Weapon, if the project chooses that contract
Damage Causer = Projectile
Event Instigator = PlayerController
Another project may choose the Pawn as projectile Owner. That is a networking and lifetime design choice; it does not change what Instigator stores.
See Get Owner / Set Owner for the ownership contract and Event AnyDamage / Apply Damage for the damage parameter flow.
Replication and authority¶
What can replicate¶
The Actor Instigator property participates in Actor replication. For clients to receive it:
- the Actor itself must be replicated and relevant to that client;
- the authoritative server must assign the Instigator;
- the referenced Pawn must be known/available to that client;
- normal replication ordering and timing still apply.
The property arriving does not guarantee every graph reads a valid Pawn on the first local frame. Actor references can resolve after related replicated objects become available. Code that reacts to replicated attribution should handle temporary absence rather than assuming spawn order is identical on every machine.
A client assigning its local copy of Instigator does not send an authoritative property change to the server. Replicated property flow is server to clients.
What does not replicate as a saved controller¶
Get Instigator Controller performs the Pawn's current controller lookup on
the calling machine. There is no separately replicated "controller at firing
time" value behind this node.
Network visibility differs by Controller type:
- an AIController normally exists only on the server;
- a PlayerController normally exists on the server and its owning client, not as a generally available Controller reference on every remote client.
Therefore a simulated client can have a valid Instigator Pawn and get None
for its Controller. That is not proof that the server lacked a controller.
The server decides gameplay credit¶
For authoritative damage:
owning client requests fire
-> server validates weapon, rate, ammo, aim, and ownership
-> server spawns authoritative projectile
-> server assigns validated firing Pawn as Instigator
-> server resolves hit and damage credit
-> replicated result drives client presentation
Do not let a client choose an arbitrary Instigator and treat it as trusted damage credit. The server should derive or verify attribution from the requesting connection and authoritative gameplay state.
Cosmetic clients may read Instigator to color a tracer, suppress local impact audio, or display a name. Those reads do not grant authority.
Stable credit across a long lifetime¶
Pawn and Controller references describe live gameplay objects. They may be too fragile for persistent scoring.
If the design must remember the shooter at the instant of creation, save the minimum stable data needed:
At authoritative spawn:
InstigatorPawn = validated firing Pawn
CreditedPlayerState = InstigatorPawn.PlayerState
CreditedTeamId = team subsystem lookup
ShotId = server-generated identifier, if audit/reconciliation needs it
Then define the fallback policy explicitly:
- Does a disconnected player still receive delayed kill credit?
- Does credit follow a possessed vehicle or its driver?
- Does a reflected projectile credit the original shooter or reflector?
- Can environmental damage have no player instigator?
- Does a team change after firing change friendly-fire treatment?
The built-in Instigator link cannot answer those design questions. It gives you a responsible Pawn reference, not an immutable combat ledger.
Avoid keeping a hard Pawn reference solely for permanent match history when a PlayerState, weak reference, ID, or copied attribution struct is the intended lifetime.
Practical Blueprint patterns¶
Initialize a projectile¶
Custom server fire logic
-> Get controlled Pawn / self Pawn
-> Spawn Actor from Class (BP_Projectile)
Instigator = validated firing Pawn
Owner = chosen network/gameplay owner
Inside the projectile:
BeginPlay
-> Get Instigator
-> Is Valid
-> cache only any richer stable attribution the design needs
Do not copy the same Pawn into a second variable merely to rename it
Instigator. Use a separate variable only when it adds a distinct contract.
Apply damage with a missing-controller policy¶
Authority-only hit handling
-> Get Instigator Controller
-> Is Valid?
true:
Apply Damage(Event Instigator = controller,
Damage Causer = self)
false:
Apply Damage(Event Instigator = None,
Damage Causer = self)
treat as environment/uncredited according to game rules
None is allowed as an event instigator. Whether it earns score is a project
policy, not something Apply Damage can infer.
The C++ twin, for the curious (our own example code):
void AExampleProjectile::ApplyValidatedDamage(
AActor* HitActor,
float DamageAmount)
{
if (!HasAuthority() || !IsValid(HitActor))
{
return;
}
APawn* ResponsiblePawn = GetInstigator();
if (HitActor == ResponsiblePawn)
{
return;
}
UGameplayStatics::ApplyDamage(
HitActor,
DamageAmount,
GetInstigatorController(),
this,
UDamageType::StaticClass());
}
Real projects still need collision validation, team rules, immunity, and anti-cheat checks around this minimal relationship.
What these getters do not do¶
They do not:
- search for a shooter or infer one from Owner;
- guarantee a non-null result;
- return the Actor itself;
- preserve the Controller that existed at spawn time;
- make a projectile ignore collision with its instigator;
- assign Event Instigator or Damage Causer automatically to a later damage call;
- create network ownership or client RPC permission;
- replicate a client-authored attribution choice to the server;
- make AIControllers exist on clients;
- keep score after Pawn/Controller lifetime changes;
- validate that the credited Pawn was allowed to cause the action.
Nearby lookalikes and follow-ups¶
- Spawn Actor from Class - pass Owner and Instigator at creation time and understand deferred collision handling.
- Projectile Movement Component and first projectile Actor - movement, collision, lifespan, and replicated projectile ownership.
- Event AnyDamage / Apply Damage - the generic damage event and its Event Instigator and Damage Causer fields.
- Apply Point Damage / Apply Radial Damage / Damage Type - hit context, radial context, and damage policy.
- Get Owner / Set Owner - a different Actor relationship with network ownership consequences.
- Possess / Un Possess / Get Controller - why the controller lookup can change.
- Is Valid - distinguish a usable object reference from an absent or pending-destruction one.
- Ownership - framework ownership, possession, and replication ownership as separate ideas.
- Replication basics - server authority, replicated variables, and RPC direction.
Go deeper¶
- AActor API - the Instigator property, replication notification, and actor-level getter surface.
- FActorSpawnParameters - native Owner and Instigator inputs used during Actor spawning.
- APawn API - the possessed Pawn and current Controller relationship.
- AController API - the controller side of possession.
For implementation archaeology, start with:
Engine/Source/Runtime/Engine/Classes/GameFramework/Actor.h-Instigator,GetInstigator, and the actor spawn surface;Engine/Source/Runtime/Engine/Private/Actor.cpp-GetInstigatorController, instigator assignment, and Actor initialization;Engine/Source/Runtime/Engine/Private/ActorReplication.cpp- actor replication and reference update paths;Engine/Source/Runtime/Engine/Private/LevelActor.cpp- native world spawn flow and spawn parameters.
Source files move across engine versions. Search for the function or property name when a path differs in your checkout.