Split Screen in UE5: Two-Player Local Co-op on Keyboard and Gamepad

Created: 2026-07-20Last updated: 2026-09-06

An introduction to turning UE5's Third Person template into two-player local co-op on one PC. Covers adding a player with Create Local Player, assigning keyboard and gamepad, and putting a label and health bar on each player's screen.

Two people walk the same stage; one presses a switch and the other goes through the opened door. Let's try that co-op on a single PC.

UE5 has a mechanism that splits the screen according to the number of players. Here we add a second player to the Third Person template so that player one uses keyboard and mouse and player two uses a gamepad . At the end, we put a name and health bar at the top-left of each screen.

The finished result: a left-right split where player one uses keyboard and mouse and player two a gamepad, with a name and health bar at each screen's top-left

What You'll Learn

  • Splitting one game screen left and right so two people walk separately
  • Assigning keyboard and gamepad to different players
  • Displaying each player's own UI on their own screen

Sponsored

One world, two viewpoints

Splitting the screen does not turn one stage into two. Two cameras each show the same stage. If player one goes behind a box, player two's screen no longer sees them. The box and both characters exist in the same world.

Two cameras showing two people on the same stage. One world with two viewpoints

UE handles three things per player here.

NameIts role here
Local PlayerA player participating on this PC. The unit that the screen splits by
Player ControllerReceives that player's input and manages the character they control
PawnThe body actually moving in the stage. Here, the Third Person character

Despite the name, a Player Controller is not the gamepad in your hands. Player one on keyboard and player two on gamepad each have their own Player Controller.

Create Local Player is the node that adds one participant to the game. Using the Third Person template's character and camera lets the added player move while their own camera follows them. The C++ function name is CreatePlayer , so some material writes it as "Create Player".

Prepare for two players

We use a Blueprint Third Person template built in UE5.5 or later on Windows. First get single-player walking and camera control working, with your connected gamepad recognized by UE. We use the template's movement logic and input settings as they are.

Place two start points

Make the level's Player Start count two. That is the candidate location where a player's character appears. Place them slightly above the floor and far enough apart that their capsules do not overlap.

You do not need to place another character directly in the level. The Third Person GameMode spawns characters based on the configured Default Pawn Class . Testing in your own level also means confirming that "World Settings → GameMode Override" is the Third Person GameMode.

Configure split screen and gamepad assignment

Set the following under "Project Settings → Maps & Modes → Local Multiplayer".

SettingValue hereMeaning
Use SplitscreenOnSplits the screen for multiple local players
Two Player Splitscreen LayoutVerticalSplits the screen left and right
Skip Assigning Gamepad to Player 1OnDoes not assign the first gamepad to 1P, starting from 2P

That last setting is what our "keyboard for 1P, gamepad for 2P" needs. Left off, the keyboard and first gamepad can end up driving the same 1P. Splitting the screen does not necessarily split input the way you want.

Assigning the keyboard to 1P's and the first gamepad to 2P's Player Controller

Keep the runtime player count at 1

In the editor's play settings, set "Number of Players" to 1 and "Net Mode" to Play Standalone , then launch with "Standalone Game".

That "Number of Players" is mainly for testing network play. Here we launch one game and add a second player inside it with a node. There is no need to set it to 2 and open another game window.

Add player two and walk around

Create one Actor for adding a player. We narrow this to starting two-player play on the same map.

  1. Create a Blueprint BP_LocalCoopSetup with Actor as the parent class and place exactly one in the level.
  2. Create a variable SecondPlayer of type Player Controller Object Reference with a default of None .
  3. In the Event Graph, wire the white exec line Event BeginPlay → Create Local Player → Set SecondPlayer .
  4. Set Create Local Player's "Controller Id" to -1 and "Spawn Player Controller" to on .
  5. Connect Create Local Player's Return Value into Set SecondPlayer's value.
Calling Create Local Player from BeginPlay and saving the returned Player Controller into SecondPlayer

An Object Reference lets you specify "which Player Controller you created" afterwards. Saving the second player returned in Return Value into SecondPlayer means you can specify the same target later when building 2P's UI. None means nothing is stored yet.

Controller Id -1 means "choose the next free ID". Spawn Player Controller, meanwhile, decides whether to create a Player Controller when adding. We turn it on because we want to control it right away.

Next, connect SecondPlayer into the Is Valid with an exec pin. That node checks whether the reference is usable right now.

  • Set SecondPlayer's exec output → Is Valid's exec input
  • Get SecondPlayer → Is Valid's "Input Object"
  • "Is Not Valid" → Print String showing "Failed to create 2P"
  • "Is Valid" can stay unconnected for now. We wire UI creation to it later.
Continuing when SecondPlayer is valid and showing a 2P creation failure when it is not

Compile and launch with Standalone Game and the screen splits left and right. Try moving 1P with the keyboard and 2P with the gamepad. Moving one without the other character moving too means input is separated as well.

Walking both characters around the same box makes the "one world, two viewpoints" relationship clear. The split-screen foundation is in place.

Input settings belong to each player too

In the Third Person template, an Input Mapping Context registers "which keys and buttons handle movement and jumping". Add Mapping Context is what makes it usable.

The Enhanced Input Local Player Subsystem that handles input is where per-player input settings are managed. The name is long, but "there is a separate one for 1P and 2P" is enough here.

If both move in the original template, no extra input nodes are needed. If you modified input handling and only 2P will not move, confirm the existing Add Mapping Context targets the Subsystem obtained from the controlling player's own Player Controller . Inside a character, Get Controller points at that player; inside a Player Controller, Self does.

Using Get Player Controller (Player Index = 0) every time touches 1P's settings while you think you are preparing 2P. Note also that Player Index is the position in the list while Controller Id is the input-side ID . Our 2P is specified via SecondPlayer rather than looked up by number.

Sponsored

How UI reaches your own screen

With both walking, add a name and health bar to each screen. Two things matter here: whose UI you create and where you display it .

Node / inputWhat it specifies
Create Widget's Owning PlayerThe Player Controller that owns this UI
Add to Player ScreenDisplays into the screen region assigned to that owner

The usual Add to Viewport positions UI relative to the whole game window. Putting both 1P's and 2P's UI at "top-left", for instance, can overlap them at the window's top-left. It is not automatically distributed one per screen.

With Add to Player Screen, the same "top-left" setting puts 1P's UI at the top-left of the left screen and 2P's at the top-left of the right screen. Changing the split to horizontal still positions each relative to its own region.

Add to Viewport overlaps UI at the whole screen's top-left while Add to Player Screen places it at each player's region's top-left

Note, though, that specifying an owner does not fill in the name or HP automatically. "Whose screen it goes on" and "what it displays" are separate. Next we pass "1P, 75%" to player one and "2P, 40%" to player two, confirming that destination and content correspond.

Hands-On: give 1P and 2P a name and health bar

When finished, each screen's top-left shows one name and one blue bar. We use fixed values here to check the bar's appearance. Logic reducing HP through damage is not added in this article.

1. Place the name and bar

Create the Widget Blueprint WBP_PlayerHUD and build this hierarchy in the Designer.

Canvas Panel
└─ Size Box (Width Override = 240)
   └─ Border (Padding = 12)
      └─ Vertical Box
         ├─ Text Block: PlayerText
         └─ Size Box (Height Override = 16)
            └─ Progress Bar: HealthBar

Set the outer Size Box's Canvas Panel Slot Anchors to top-left , Position to X=16, Y=16 , Alignment to X=0, Y=0 , and Auto Size on . Set the inner Size Box's Vertical Box Slot horizontal setting to "Fill" to give the bar its width.

Rename PlayerText and HealthBar and turn on Is Variable for both. That lets the Graph specify "which text and which bar to change".

Setting PlayerText's text to "1P" and HealthBar's "Percent" to 0.75 temporarily lets you check the look in the Designer. Use a light grey background and a blue bar, or similar colors that distinguish empty space from the remaining amount.

Percent is a ratio from 0 to 1. 0 is empty, 1 is full, and 0.75 fills three quarters. Do not enter 75 directly when displaying 75%.

A 240-wide HUD with the health bar under the name, and the hierarchy from Canvas Panel down to PlayerText and HealthBar

2. Display the passed name and ratio

Create a function ConfigureHUD in WBP_PlayerHUD and add these inputs. It exists to "set the name and bar ratio on this UI".

Input nameTypeWhat it receives
InLabelText"1P" or "2P"
InRatioFloatA ratio such as 0.75 or 0.4

Function inputs come from the entry node's output pins, or search Get InLabel and Get InRatio by right-clicking inside the function. The diagrams use Gets to keep wiring readable. No new variables are needed.

Wire the exec line from the function's entry in this order.

  1. Set Text : connect PlayerText's Get into "Target" and InLabel into "In Text".
  2. Set Percent : connect HealthBar's Get into "Target". Pass InRatio through Clamp (Float) with Min=0 and Max=1, and connect that Return Value into "In Percent".
ConfigureHUD passing InLabel into PlayerText's Set Text

Clamp keeps a value within a specified range. Here we bring it into 0 to 1 before passing it to the bar. Compile and save.

Clamping InRatio to 0 through 1 and passing it into HealthBar's Set Percent

3. Create the UI with an owner specified

Return to BP_LocalCoopSetup and create a function AddHUDForPlayer . So 1P and 2P use the same procedure, it takes the owner, name, and ratio as inputs.

Input nameType
OwnerControllerPlayer Controller Object Reference
PlayerLabelText
HealthRatioFloat

First pass OwnerController into the Is Valid with an exec pin. "Is Not Valid" shows "HUD owner not found" with Print String and ends; "Is Valid" continues.

  1. Choose WBP_PlayerHUD as Create Widget 's Class and connect OwnerController into "Owning Player".
  2. Call ConfigureHUD from its Return Value. Pass PlayerLabel into "In Label" and HealthRatio into "In Ratio".
  3. Then call Add to Player Screen . "Target" is the same Create Widget Return Value. "Z Order" can be 0.
Creating WBP_PlayerHUD with OwnerController as Owning Player and passing the Return Value into the next ConfigureHUD's Target

Create Widget's Return Value here is the UI you just created . Pass that same UI into both ConfigureHUD and Add to Player Screen. Class is "which kind to create" while Return Value is "what was actually created".

Using the same Create Widget Return Value as Target and passing PlayerLabel and HealthRatio into ConfigureHUD

Add to Player Screen's Return Value is a Boolean reporting whether display succeeded. Wire its exec output into a Branch and the Return Value into that Condition, with the False side showing "Failed to display HUD" via Print String. The True side ends this function.

Branching on Add to Player Screen's success and going to Print String on failure

4. Create 1P's and 2P's UI in turn

Return to BP_LocalCoopSetup's Event Graph. On the "Is Valid" side you left open after adding the second player, connect two AddHUDForPlayer calls in order.

Call orderOwner ControllerPlayer LabelHealth Ratio
FirstGet Player Controller (Player Index=0)'s Return Value1P0.75
SecondGet SecondPlayer2P0.4
Passing 1P's Player Controller with the name 1P and ratio 0.75 into AddHUDForPlayer

Player Index=0 retrieves 1P, who has participated from the start. 2P uses the SecondPlayer returned by Create Local Player.

Passing the saved SecondPlayer with the name 2P and ratio 0.4 into AddHUDForPlayer

Relaunch, and success is "1P" with a three-quarter bar on the left screen and "2P" with a 40% bar on the right. Confirm both appear at the top-left of their own screen .

As a test, change only the second call's Health Ratio from 0.4 to 0.2 and relaunch. 1P's bar is unchanged and only 2P's shortens. Even using the same Widget Blueprint, the created UIs are separate, so you can pass each a different value.

Linking to real HP works the same way. Read the HP of the character the owner controls and pass it to that UI. Inside a Widget, Get Owning Player Pawn retrieves the owner's Pawn. For how to hold HP and handle damage, see the health and damage introduction.

Sponsored

When it does not work

The screen does not split, or 2P's character does not appear

First confirm one BP_LocalCoopSetup is placed in the level and the exec line runs from BeginPlay through Create Local Player. "Failed to create 2P" means Return Value is not usable.

If SecondPlayer is valid, next get Get Controlled Pawn from SecondPlayer and check it with Is Valid. If that is invalid, investigate the GameMode's Default Pawn Class and whether a Player Start overlaps a wall, floor, or another character.

If the Pawn is valid too but the display is wrong, check the character's camera settings and Use Splitscreen. Rather than concluding "a black screen means missing Player Starts", checking Controller → Pawn → camera and display settings in order narrows down what to fix.

Only 2P will not move, or the gamepad moves 1P

Confirm the gamepad is recognized and the launched game window has focus. Then check whether Skip Assigning Gamepad to Player 1 is on, whether an Input Mapping Context is added to 2P's own Subsystem, and whether that Context registers gamepad keys.

Older UE versions have known issues with this gamepad assignment setting. Trying a fresh Third Person project on UE5.5 or later, matching this article's conditions, makes it easier to separate from your own input logic.

The UI overlaps, or both show the same HP

For a positioning problem, check Create Widget's Owning Player and Add to Player Screen's Target. Confirm you call Create Widget separately for 1P and 2P and specify each one's Player Controller as the owner.

If positions are right but both show 75%, check the Health Ratio you pass. Nothing infers and displays HP from the owner setting. Trace ConfigureHUD's inputs and the connections through Set Percent.

Bonus: split orientation and where to go next

Try a horizontal split

Setting Two Player Splitscreen Layout to Horizontal splits top and bottom. Vertical is left-right and Horizontal is top-bottom. A left-right split makes each screen tall and narrow, and a top-bottom split makes them wide.

The HUD we built positions relative to each player's region, so you can test whether it still fits at each screen's top-left after switching. Walk around and compare whether distant enemies are easier to spot, whether your feet get cut off, and whether the UI is in the way, then choose the orientation that suits your game.

Player count, performance, and online are separate matters

Our setup adds one 2P to the initial 1P each time the game launches. Adding drop-in joining or level transitions requires management that avoids adding a player who already exists.

Two cameras also increase rendering work. That does not mean processing time always exactly doubles, though. Show the same location with one player and with two and compare how heavy it runs.

This exercise shares one world inside a single PC. Online play between separate PCs needs a mechanism for conveying game state to the other side. Starting small, with two people walking around the same box or pressing separate switches, makes it easier to build up.

Summary

Adding a participant with Create Local Player and enabling split screen lets you view one stage from separate cameras. Using keyboard and gamepad here, we configured input assignment to match.

UI follows the order decide the owner and create it, pass that person's values, and display with Add to Player Screen . Thinking of those three separately lets one HUD show 1P's and 2P's own states.

Further Reading

Unreal Engine Notes in this section98