Create Local Player / Get Num Player Controllers¶
At a glance
Lives in: Blueprint API / Game; implemented by Gameplay Statics and
GameInstance - Returns: Create Local Player returns the new
PlayerController if one is created; count nodes return integers -
Fails by: returning None or a count that means something different on
server, client, or dedicated server - Official docs:
Create Local Player,
Get Num Player Controllers,
Get Num Local Player Controllers,
and Local Multiplayer
The one-minute version¶
- A local player is a player using this machine: keyboard/gamepad/split screen on this process.
Create Local Playeradds another local player, usually for couch multiplayer. IfSpawn Player Controlleris true, it can return the createdPlayerController.- Local multiplayer is not network multiplayer. Two local players can share one machine; network clients are separate machines/processes.
Get Num Player Controllerscounts available PlayerControllers for the current machine's world, including remote controllers when called on the server.Get Num Local Player Controllerscounts fully initialized local players and is0on a dedicated server.- These nodes do not create remote clients, guarantee the same player index on every machine, or automatically give each local player UI and mapping contexts.
What they actually do¶
Think of local players as viewport/input slots inside one game instance:
flowchart LR
GI[GameInstance on this process] --> LP0[LocalPlayer 0]
GI --> LP1[LocalPlayer 1]
LP0 --> PC0[PlayerController 0]
LP1 --> PC1[PlayerController 1]
Create Local Player adds a ULocalPlayer to the current GameInstance.
Blueprint exposes the practical result: if a PlayerController is spawned now,
you get that controller reference back.
pseudocode of the engine behavior - not engine source
function CreateLocalPlayer(ControllerId, SpawnPlayerController):
LocalPlayer = GameInstance.CreateLocalPlayer(ControllerId)
if LocalPlayer could not be created:
return None
if SpawnPlayerController:
return LocalPlayer.PlayerController
return None
function GetNumLocalPlayerControllers():
return count of fully initialized local players with controllers
function GetNumPlayerControllers():
return count of available player controllers in this world
The difference matters most in multiplayer. On a dedicated server, there are no local players. On a listen server, the host has a local player and also sees server-side controller objects for connected players. On a client, remote PlayerControllers generally are not available.
When they fail (and what failure does)¶
Common causes:
- Local multiplayer is not enabled by design. Your game mode/UI/camera setup may assume one local player even if the node can create another.
Spawn Player Controlleris false. The node may add the local player but returnNonebecause the controller will be created later, often during map travel.- Controller ID is unavailable or mismatched.
-1means "choose the next available ID"; explicit IDs can collide or not map to the device you expect. - You used the wrong count.
Get Num Player ControllersandGet Num Local Player Controllersanswer different questions. - The code ran on a dedicated server. Dedicated servers have no viewport and no local players.
- Widgets were created with the wrong owning player. Player 1's UI needs Player 1 as owner, not hard-coded player index 0.
- Enhanced Input contexts were added only for player 0. Each local player has its own local-player subsystem/mapping context setup.
Failure does not spawn fallback UI, remap devices, or make player index order
stable across server and clients. You get a controller reference or None, and
your setup graph must handle both.
The pattern everyone actually uses¶
For couch co-op from a menu:
Host selects Add Player
-> Create Local Player(Controller Id = -1, Spawn Player Controller = true)
-> Is Valid Return Value
-> create HUD with Owning Player = returned PlayerController
-> add gameplay mapping context for that local player's subsystem
-> let GameMode spawn/restart the pawn for that controller
For UI setup in split-screen:
For each local PlayerController
-> Create Widget WBP_PlayerHUD with Owning Player = that controller
-> Add to Player Screen / viewport path appropriate for local player
For network scoreboards, do not iterate PlayerControllers from a client. Use GameState's PlayerArray and PlayerStates instead.
The C++ twin, for the curious (our own example code):
void ULocalCoopMenu::AddLocalPlayer()
{
FString Error;
ULocalPlayer* LocalPlayer =
GetGameInstance()->CreateLocalPlayer(-1, Error, true);
if (!LocalPlayer || !LocalPlayer->PlayerController)
{
ShowAddPlayerError(Error);
return;
}
CreateHudFor(LocalPlayer->PlayerController);
}
Player index traps¶
Player Index 0 is a local-machine convenience, not a universal identity:
- In single-player, it usually feels like "the player."
- In split-screen, player 0 and player 1 are both local, and each needs the right owning controller.
- In network play, index order can differ between server and clients.
- Remote clients usually cannot get other players' PlayerControllers.
Use PlayerState for public player data, PlayerController for local input/UI, and Pawn/Character for the current body.
Lookalikes - which one do I want?¶
| Node / object | Returns / changes | Use when |
|---|---|---|
| Create Local Player | Adds a local player; may return a new PlayerController | Couch co-op / split-screen on one machine. |
| Remove Player | Removes a local player | A local split-screen player leaves. |
| Get Num Local Player Controllers | Count of fully initialized local players | You are iterating local input/UI owners. |
| Get Num Player Controllers | Count of available controllers for this world/machine | Server/listen-server code needs available controller count. |
| Get Player Controller(index) | A controller from that machine's list, or None |
You need a specific local input/UI owner. |
| PlayerState / GameState PlayerArray | Public replicated player records | Scoreboards, names, teams, ready state. |
| Network multiplayer session travel | Remote players join as separate machines/processes | You are building online multiplayer, not couch co-op. |
Rule of thumb: LocalPlayer is viewport/input on this machine; PlayerController owns input/UI; PlayerState is the public player record everyone can read.
Going deeper¶
- Get Player Character / Pawn / Controller
- player-slot getters and index traps.
- Get Game Mode / Game State / Player State
- PlayerState and GameState for public multiplayer data.
- Set Input Mode & Show Mouse Cursor
- per-local-player UI focus and cursor setup.
- Add Mapping Context - adding Enhanced Input contexts to the correct local player.
- HUD state from replicated and local data
- split local UI from replicated state.
- Official docs: Create Local Player, Get Num Player Controllers, Get Num Local Player Controllers, and Local Multiplayer.
- Engine source (requires engine access - we do not reproduce it here):
UGameplayStatics::CreatePlayer,UGameplayStatics::GetPlayerController,UGameplayStatics::GetNumPlayerControllers, andUGameplayStatics::GetNumLocalPlayerControllersinEngine/Source/Runtime/Engine/Private/GameplayStatics.cpp;UGameInstance::CreateLocalPlayerinEngine/Source/Runtime/Engine/Private/GameInstance.cpp.