Skip to content

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 Instigator returns the Actor's stored Pawn reference.
  • Get Instigator Controller first 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 Class call. 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 Instigator advanced pin on Spawn 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:

  1. The Actor was spawned without an Instigator.
  2. The Actor was placed in a level rather than caused by a Pawn.
  3. A non-Pawn system created it and did not choose a responsible Pawn.
  4. The stored Pawn has been destroyed or is no longer available.
  5. The Pawn exists but currently has no Controller.
  6. The graph is running on a client where that Controller does not exist.
  7. 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 Actors or 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:

  1. the Actor itself must be replicated and relevant to that client;
  2. the authoritative server must assign the Instigator;
  3. the referenced Pawn must be known/available to that client;
  4. 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

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.