Skip to content

Possess / Un Possess / Get Controller

At a glance

Lives in: Blueprint API / Pawn - Main targets: Controller for Possess and Un Possess, Pawn for Get Controller - Returns: Possess / Un Possess return no success value; Get Controller returns a Controller reference that can be None - Fails by: doing nothing useful or returning None; no Blueprint failure pin - Official docs: Possess, Un Possess, Get Controller, and Controllers

The one-minute version

  • Possess makes a Controller drive a Pawn. The controller is the brain; the pawn is the body.
  • Un Possess makes the controller let go of its current pawn. The pawn is now uncontrolled unless something else possesses it.
  • Get Controller asks a specific pawn, "who is driving you right now?" It can return a PlayerController, an AIController, another controller subclass, or None.
  • Possess is authority work. In multiplayer, the server normally decides possession; a client-side call does not make the server accept a new body.
  • Possession is not the same thing as camera view, attachment, actor Owner, or player-slot lookup. It changes the control link.
  • The nodes do not spawn a pawn, choose a PlayerStart, create an AIController, fix input mappings, or return a success Boolean. You still need to verify the new control link.

What they actually do

The useful mental model is a two-way link:

flowchart LR
    PC[PlayerController or AIController] -- possesses --> Pawn[Pawn or Character]
    Pawn -- Get Controller --> PC
    PC -- Get Controlled Pawn --> Pawn

Possess is called on the controller, not on the pawn:

Possess
Target = Controller
In Pawn = Pawn to control

The behavior is roughly:

pseudocode of the engine behavior - not engine source

function Controller.Possess(NewPawn):
    if this machine is not authority for possession:
        return

    if NewPawn is None:
        return

    if Controller already has a pawn:
        unpossess the old pawn

    Controller.CurrentPawn = NewPawn
    NewPawn.Controller = Controller
    notify controller and pawn that possession changed

function Controller.UnPossess():
    OldPawn = Controller.CurrentPawn
    if OldPawn is None:
        return

    Controller.CurrentPawn = None
    OldPawn.Controller = None
    notify controller and pawn that possession ended

function Pawn.GetController():
    return Pawn.Controller, or None

For a player, that link lets input and control rotation drive the pawn. For an AI pawn, it lets the AIController run behavior, path following, and movement requests.

The broader concept is covered in Possession.

When they fail (and what failure does)

Possess and Un Possess have no success or failed pin. Get Controller returns None when the pawn is currently uncontrolled.

Common causes:

  1. The call ran on the wrong machine. Possess is authority-only. A client can request a pawn switch through an owned server event, but the server performs the actual possession.
  2. Target Controller is None. There is no brain to drive the pawn.
  3. In Pawn is None or not valid. The controller cannot possess an empty or destroyed body.
  4. The pawn was never auto-possessed. A placed player pawn may have the wrong Auto Possess Player setting. A placed AI pawn may have no AIController class or Auto Possess AI setting.
  5. The controller possessed something else. A controller normally drives one pawn at a time. Switching vehicles or respawning leaves the old pawn unpossessed.
  6. You checked too early or after destruction. During spawn, death, respawn, or EndPlay, Get Controller can temporarily be None.
  7. Input or AI setup is the real problem. Possession can be correct while Enhanced Input mapping contexts, movement components, Behavior Trees, or NavMesh setup are still wrong.

Failure does not retry later, choose a fallback pawn, spawn a controller, or print a guaranteed warning for your project logic. Use prints and Is Valid checks to prove the controller, pawn, and machine before you blame input or AI.

The pattern everyone actually uses

For normal player start/respawn, let GameMode do the framework work:

GameMode Restart Player at Player Start
-> GameMode spawns/selects pawn
-> PlayerController possesses pawn
-> PlayerController/Pawn setup events rebind UI, input, and camera

Use explicit Possess when you intentionally own the swap:

Server-side PlayerController EnterVehicle
-> Is Valid VehiclePawn
-> Possess(VehiclePawn)
-> confirm Get Controlled Pawn == VehiclePawn
-> apply vehicle input mapping context on owning client

For AI debugging:

Enemy BeginPlay or debug key
-> Get Controller
-> Is Valid
-> Cast To BP_EnemyAIController
-> print controller name before debugging Move To / Behavior Tree

If the pawn has no controller, fix possession first. AI Move To cannot drive a pawn that has no AIController.

The C++ twin, for the curious (our own example code):

void ATrainingPlayerController::PossessVehicle(APawn* VehiclePawn)
{
    if (!HasAuthority() || !IsValid(VehiclePawn))
    {
        return;
    }

    Possess(VehiclePawn);
}

void ATrainingEnemy::BeginPlay()
{
    Super::BeginPlay();

    AController* CurrentController = GetController();
    if (!IsValid(CurrentController))
    {
        return;
    }

    CachedAIController = Cast<ATrainingAIController>(CurrentController);
}

Possession is not view target

This is a common beginner trap:

  • Possession decides which pawn receives control.
  • View target decides which actor the PlayerController's camera manager uses for the camera.

You can view through a CameraActor without possessing it. You can possess a pawn and temporarily view through a death camera. Those are separate choices.

For camera cuts, use Set View Target with Blend. For body/control changes, use possession through the server/authority path.

Multiplayer rule

In a networked game, possession is server-owned state.

Beginner-safe shape:

Owning client presses "Enter Vehicle"
-> Run on Server event on owned PlayerController or pawn
-> server validates vehicle is usable
-> server calls Possess(VehiclePawn)
-> possessed pawn/controller state replicates
-> owning client updates local input/UI/camera presentation

Do not have the client call Possess locally and expect everyone else to agree. It may change a local-looking reference briefly, but the server's state is the one that matters.

Lookalikes - which one do I want?

Node or setting Returns / changes Use when
Possess Controller starts driving a pawn; no success return Authority deliberately changes the controlled body.
Un Possess Controller releases its current pawn; no success return You need a spectator/uncontrolled state or a controlled swap.
Get Controller Pawn's current controller, or None A pawn needs to know who is driving it.
Get Controlled Pawn / Get Pawn Controller's current pawn, or None You already have the controller and need its body.
Get Player Controller Player slot's controller, or None You need a local player/control/UI owner, not any pawn's driver.
Try Get Pawn Owner AnimBP mesh owner if it is a pawn You are inside an Animation Blueprint.
Spawn Default Controller Creates default AI controller when configured A pawn should get its AIController after spawn/setup.
Set View Target with Blend Camera view changes The player should look through another actor without changing control.
Set Owner Actor network owner changes You are fixing RPC/owner-only replication ownership, not control.

Rule of thumb: Possession answers "who drives this pawn?" Actor Owner answers "which player connection owns this actor?" View target answers "what camera am I looking through?"

Going deeper