Get Player Character / Get Player Pawn / Get Player Controller¶
At a glance
Lives in: Blueprint API / Game; implemented by Gameplay Statics -
Returns: PlayerController, Pawn, or Character for a player index;
each can be None -
Fails by: returning None when the index has no available player
controller, the controller has no pawn, or the pawn is not a Character -
Official docs: Get Player Controller,
Get Player Pawn,
and Get Player Character
The one-minute version¶
- These nodes are shortcuts from the current world to a player slot.
Player Index 0usually means "the first local player" in a normal single-player Play session. Get Player Controllergets the player's controller: input, camera/control rotation, UI ownership, and possession decisions.Get Player Pawngets the pawn currently possessed by that controller. It can be anyPawnsubclass: aCharacter, vehicle, spectator pawn, custom flying pawn, and so on.Get Player CharacterisGet Player Pawnplus a character check. It returnsNoneif the player is controlling a pawn that is not aCharacter.- These nodes are for players, not every actor in the level. They do not find enemies, non-player characters (NPCs), overlap partners, or all connected multiplayer users.
- In multiplayer,
Player Index 0is not a portable way to say "the host," "the server," or "that other player." The available controller list differs between server and clients.
What they actually do¶
The three nodes all start with the same hidden context: "which game world am I asking about?" In Blueprint, Unreal supplies that world context from the object running the graph.
From there, the nodes walk the available player-controller list for that world. Epic's docs describe the order as local players first, followed by available remote player controllers. The important beginner translation is:
- in ordinary single-player, index
0is your one player; - in local split-screen, index
0,1, and so on are local players on the same machine; - on a network client, remote players'
PlayerControlleractors are not available, so the list normally contains only local players; - on the server, remote players have server-side player controllers, so the list can include connected clients.
The relationship looks like this:
flowchart LR
World[Current world] --> PC0[PlayerController at Player Index 0]
PC0 -- possesses --> Pawn[Pawn]
Pawn -. may be .-> Character[Character]
And the behavior is roughly:
pseudocode of the engine behavior - not engine source
function GetPlayerController(WorldContext, PlayerIndex):
World = find the world from WorldContext
return the available PlayerController at PlayerIndex, or None
function GetPlayerPawn(WorldContext, PlayerIndex):
Controller = GetPlayerController(WorldContext, PlayerIndex)
if Controller is None:
return None
return Controller's currently possessed Pawn
function GetPlayerCharacter(WorldContext, PlayerIndex):
Pawn = GetPlayerPawn(WorldContext, PlayerIndex)
if Pawn is a Character:
return Pawn
return None
That last step is the reason Get Player Character can fail even when a player
exists. A Character is a specific kind of Pawn; not every playable body is
a Character. The class ladder is covered in
The gameplay class hierarchy.
When they fail (and what failure does)¶
All three nodes can return None.
Common causes:
- There is no player at that index. Single-player games usually only have
index
0. Asking for index1returnsNoneunless a second local player or available remote player controller exists on that machine. - You are on the wrong network machine. A client generally cannot retrieve
other players'
PlayerControlleractors. Use replicatedPlayerStatedata when the question is about all connected players. - The controller exists but has no pawn right now. This happens during
spawn timing, death/respawn, spectator transitions, or explicit
unpossession.
Get Player Controllermay succeed whileGet Player PawnandGet Player CharacterreturnNone. - The pawn is not a
Character. Vehicles, spectator pawns, and custom pawn classes makeGet Player Pawnsucceed whileGet Player CharacterreturnsNone. - You are asking during construction. These Gameplay Statics nodes are
marked unsafe during actor construction. For gameplay setup, prefer
BeginPlay, possession events, widget initialization with an owning player, or a later point where the world and controller are known.
Failure has no hidden side effect. These nodes do not spawn a player, create a
controller, possess a pawn, search the whole level, or wait until the player
exists. They are pure getters: they return the current reference, or None.
Guard the result with Is Valid before using it in a graph where timing or networking can make the reference empty.
The pattern everyone actually uses¶
For a first single-player character project, this is the normal one-time setup:
BeginPlay
-> Get Player Character (Player Index 0)
-> Cast To BP_YourCharacter
-> store OwnerCharacter
Use the stored reference after an Is Valid check, especially in widgets,
manager actors, or animation-adjacent logic that can outlive the current pawn.
For player-facing UI, you usually want the controller instead:
BeginPlay or widget setup
-> Get Player Controller (Player Index 0)
-> Create Widget / Set Input Mode / Show Mouse Cursor
For overlap, hit, interaction, and damage events, do not start with
Get Player Character unless the interaction is explicitly about the local
player. Use the event's reference first:
OnComponentBeginOverlap
-> Other Actor
-> Cast To BP_YourCharacter
That pattern answers "what touched me?" The player getter answers "who is in player slot N?" Those are different questions.
The C++ twin, for the curious (our own example code):
void AMyPickup::BeginPlay()
{
Super::BeginPlay();
ACharacter* PlayerCharacter =
UGameplayStatics::GetPlayerCharacter(this, 0);
if (!IsValid(PlayerCharacter))
{
return;
}
CachedPlayerCharacter = PlayerCharacter;
}
Player Index 0 is not "the player" in every game¶
Player Index 0 is convenient because most tutorials are single-player. It is
also the source of many beginner multiplayer bugs.
Use this rule of thumb:
| Situation | What index 0 usually means |
Safer thought |
|---|---|---|
| Single-player | The only local player | Fine for first-project code. |
| Local split-screen | First local player on this machine | Pass the right local index or owning player. |
| Network client | This client's local player | It is not another client. |
| Listen server | The host's local player, plus server-side remote controllers may also be available | Do not assume the same index maps to the same human everywhere. |
| Dedicated server | A server-side available player controller, if connected players exist | There is no local human viewport. |
If you need "all players in the match," do not loop Get Player Character on
every client and expect the same list. Use PlayerState data through the
GameState, or server-owned logic that has the references it needs.
Lookalikes - which one do I want?¶
| Node | Returns | Use when |
|---|---|---|
| Get Player Controller | PlayerController or None |
You need input/UI/camera ownership for a player slot. |
| Get Player Pawn | Pawn or None |
You need the body currently possessed by that player slot, and it might not be a Character. |
| Get Player Character | Character or None |
You are in a standard character project and need the player body as a Character. |
| Get Controller | Controller from a specific pawn | A pawn needs to know who is driving it, including AI. |
| Get Controlled Pawn | Pawn from a specific controller | You already have the controller and need its body. |
| Try Get Pawn Owner | Pawn from an Animation Blueprint's mesh owner | You are inside an AnimBP and need the pawn being animated. |
| Get Owning Player / Get Owning Player Pawn | Widget's assigned player or pawn | You are inside a widget and should use the widget's owner instead of guessing index 0. |
| Get Player State | Replicated player identity/state | You need connected-player data that exists on clients and server. |
| Get Actor Of Class | Some actor of a class | You are not asking about a player slot; use sparingly because it searches the world. |
Rule of thumb: start from the reference Unreal already gave you. Use player
getters for "my local player slot," event pins for "the thing involved in this
event," pawn/controller getters for possession,
and PlayerState for multiplayer identity.
Going deeper¶
- Possession - why the PlayerController and Pawn are separate objects.
- The gameplay class hierarchy - why
every
Characteris aPawn, but not everyPawnis aCharacter. - Get Velocity - the common next step after you have the player character reference.
- Try Get Pawn Owner - the Animation Blueprint-specific way to get the pawn being animated.
- Official docs: Get Player Controller, Get Player Pawn, Get Player Character, Get Num Player Controllers, and Get Player State.
- Engine source (requires engine access - we do not reproduce it here):
UGameplayStatics::GetPlayerController,UGameplayStatics::GetPlayerPawn, andUGameplayStatics::GetPlayerCharacterinEngine/Source/Runtime/Engine/Private/GameplayStatics.cpp; declarations inEngine/Source/Runtime/Engine/Classes/Kismet/GameplayStatics.h.