You have a character walking with WASD and jumping with Space. Now let's take your hands off the keyboard and walk the same place with a gamepad.
Enhanced Input lets you add pad assignments while reusing the movement and jump logic. The character moving is not the finish line, though. Whether it stops when you let go, and whether you can keep playing with the pad alone after opening a menu, is what changes how it feels.
This article builds up to walking with the left stick, jumping with a button, choosing a menu item, and returning to the game . We also try Common Input at the end, for building displays that match the input method.
What You'll Learn
- Adding a pad's stick and buttons to the same Input Action
- The Dead Zone that ignores small inputs, and how to think about tuning it
- The difference between a trigger's press depth and the conditions that fire an input
- The menu's initial selection and returning control to the game
- Add the pad to the same movement and jump
- Tidy small inputs with a Dead Zone
- Triggers separate press depth from firing conditions
- Open a menu and select the first button
- Hands-On: complete a loop with the pad alone
- Check the current input method with Common Input
- Checks for when it does not work
- Bonus: how to think about broadening support
- Summary
Add the pad to the same movement and jump
We use BP_InputPractice from the Enhanced Input introduction, the white practice character that moves with WASD and jumps with Space. If you switched to driving mode, return to walking before trying this.
We use one Xbox-style pad recognized on Windows as the example. Button letters and connection methods differ by model. First confirm the OS recognizes the pad, then click UE's Play screen to direct input to the game.
Add two rows to the IMC
Stop Play and add these assignments to IMC_PlayerControls. Keep the existing WASD and Space.
| Input Action | Key to add | Value received |
|---|---|---|
| IA_PracticeMove | Gamepad Left Thumbstick 2D-Axis | X for left-right, Y for forward-back |
| IA_PracticeJump | Gamepad Face Button Bottom | Pressed or not |
2D-Axis reads the stick's horizontal and vertical together. It differs from "Gamepad Left Thumbstick" 's click button and from X-axis-only inputs, so read to the end of the name in the key picker.
Leave Modifiers and Triggers empty on the two new pad rows at first. The stick already carries X and Y, so there is no need to copy the W/S Swizzle or A/S Negate.
If you also worked through the key-rebinding article, set the added pad jump row's Setting Behavior to Ignore Settings . That keeps this row out of rebinding and leaves the keyboard's JumpKey as a single slot. Do not change the Space row's Override Settings or Name.

First, walk and jump
Save and Play, then tilt the left stick in each direction. The input's X is horizontal and Y is forward-back. The Add Movement Input built in the Enhanced Input introduction receives that value as is.
Pressing the pad's bottom face button calls Jump from IA_PracticeJump. On Xbox-style pads that is A. Even if you rebound Space to J, the added pad row still calls the same jump.
What changed is the entry point. Walking and jumping logic stays shared , and now both WASD and the pad work.
Tidy small inputs with a Dead Zone
A stick does not always return exactly to 0 when you let go. When that small offset reaches movement, the character creeps along. This state of lingering unintended input is called drift .
A Dead Zone treats small inputs near the center as 0. Thinking of it as adjusting "how far you must tilt before it starts moving" makes its relationship to feel clearer.
1. Look at the input before tuning
Open the console during Play and run showdebug enhancedinput . The console usually opens with the tilde key. On layouts where it will not, you can assign a key you are not using during practice under "Project Settings → Input → Console Keys".
Watch the displayed IA_PracticeMove value while you tilt the stick and return it to center. Without touching the keyboard, see how much input remains. What you see is the value reaching UE, not the pad's raw internal sensor value.
Even on a pad with no drift, remembering how it responds to a slight tilt lets you compare after configuring.
2. Add a Dead Zone to the stick row
Stop Play and add a Dead Zone to the Modifiers on IMC_PlayerControls' Gamepad Left Thumbstick 2D-Axis row .
| Item | Value here | Meaning |
|---|---|---|
| Type | Radial | Judges by distance from center combining X and Y |
| Lower Threshold | 0.2 | Treats inputs smaller than this as 0 |
| Upper Threshold | 1.0 | Output reaches its maximum of 1 at this magnitude |
A threshold is the boundary where handling switches. Lower is the boundary where motion starts and Upper where it maxes out. Radial handles it as a circle, distinct from Axial, which judges X and Y separately.
Adding it to the whole IA also applies it to the keyboard using the same IA. Adding it to the stick row here tunes only the pad.

3. Confirm both "stopping" and "moving a little"
Save, Play again, and compare input values with the motion. An input magnitude of 0.1, for instance, becomes 0 after this setting. An input of 0.6, meanwhile, becomes 0.5, because the remaining 0.2 to 1.0 range is stretched back across an output of 0 to 1.
Raising Lower ignores more small offsets but also makes slow walking from a slight tilt harder. 0.2 is a starting point for tuning. Find a value that stops when you let go while keeping the fine control you want.
When done, run the same showdebug enhancedinput again to clear the display. If it keeps moving with input at 0, investigate movement logic or external forces rather than the Dead Zone.
Triggers separate press depth from firing conditions
The RT/LT on a pad's back are analog triggers reading how far you pressed as 0 to 1. A light press gives a small value and a deep press approaches 1.
Enhanced Input also has a setting called Triggers, but those are conditions for "what input makes the action fire". The physical trigger on a pad and input firing conditions are different things.

Display the press depth
Create IA_TriggerPractice in the InputPractice folder with Value Type Axis1D (float). Leave the IA's Modifiers and Triggers empty.
Add IA_TriggerPractice to IMC_PlayerControls and choose the key Gamepad Right Trigger Axis . Entries without Axis, meant for buttons, cannot handle press depth the same way.
Place the IA_TriggerPractice event in BP_InputPractice. Wire a white line from Triggered into Print String, connect Action Value into In String with a Float-to-String conversion node in between, and set Duration to 0. From the same IA_TriggerPractice event's Completed, display 0 for two seconds with a separate Print String. The two diagrams below split the wiring coming from one event.

Save and Play, then press the right trigger lightly and then deeply. Releasing displays 0. Preparing the Completed side too distinguishes "the display just went away" from "the input returned to 0".

React only at the moment you press past a threshold
Stop Play and add Pressed to IA_TriggerPractice's Triggers with an Actuation Threshold of 0.5 . Change the Print String wired to Triggered to Duration 2.
That gives practice with reacting once when input crosses the 0.5 boundary. Press lightly, then deeply, and hold. Holding does not add displays; releasing and pressing again reacts once more.
With this setting you can no longer treat Completed as "the moment of physical release", so disconnect the earlier Completed → Print String white line. Pressed is a condition that does not maintain a Triggered state while you keep holding after it fires.

An accelerator uses press depth while a single shot uses the moment of firing. This example is an experiment displaying input, so it adds no logic for cars or projectiles.
Open a menu and select the first button
With the character moving, a menu comes next. A mouse points directly at a button, while a pad's D-pad moves from what is currently selected to the next thing.
Focus is the UI selection that the confirm button acts on. It differs from moving a mouse cursor. Deciding the selection right after a screen opens lets you keep going with the pad in hand.
Here we build two buttons, "Resume" and "Controls". To confirm entering and leaving the screen first, we do not add a pause that stops game time.
1. Line up two buttons
Create a Widget Blueprint named WBP_PadMenu . In the Designer, put a Vertical Box at the Canvas Panel's center about 400 wide and stack these parts.
| Part | Name | Display and settings |
|---|---|---|
| Text | for a heading | Menu |
| Button + Text | ResumeButton | Resume. Is Variable and Is Focusable on |
| Button + Text | HelpButton | Controls. Is Variable and Is Focusable on |
| Text | HelpText | Empty at first. Is Variable on |
Turn Is Focusable on for WBP_PadMenu itself in Class Defaults too. Leave button-to-button Navigation at defaults and start from the two stacked vertically. UMG basics are covered in the Widget Blueprint introduction.
To see the selection clearly during practice, set Render Focus Rule to Always under "Project Settings → User Interface". That draws a frame on the focused part.

2. Build a function that selects the first button
Create a function FocusFirstButton in WBP_PadMenu with no inputs or outputs.
Wire a white line from the function entry into Set User Focus . Target is the Designer's ResumeButton placed as a Get, and Player Controller is Get Owning Player .
Set User Focus means "move this player's selection to this part". Use the one with a Widget Target and a Player Controller input , not the same-named node for Event Reply. After making the function, compile and save the Widget.

3. Open the screen with a menu button
Create a Digital (Bool) IA_OpenPadMenu in the InputPractice folder. Leave Triggers empty and assign Gamepad Special Right and the keyboard M in IMC_Common. On Xbox-style pads that is the Menu/Start button.
In BP_InputPractice, call Create Widget from IA_OpenPadMenu's Started. Class is WBP_PadMenu and Owning Player is Get Player Controller (Player Index=0).
Promote the Return Value to a variable named PadMenuWidget . Connect the white line in this order.
- Create Widget → Set PadMenuWidget
- Add to Viewport (Target Get PadMenuWidget)
- Set Input Mode UI Only
- Set Show Mouse Cursor=true
- FocusFirstButton (Target Get PadMenuWidget)

UI Only's Player Controller is Get Player Controller and In Widget to Focus is Get PadMenuWidget. Mouse Lock Mode is Do Not Lock, and turn Flush Input on where the version has it. The mouse cursor's Target is the same Controller.

Display it, then hand focus to the resume button last. Directing input to the screen with UI Only and deciding which button within it is selected go in that order.

4. Wire the controls button and the return logic
In WBP_PadMenu, from HelpButton's On Clicked call Set Text targeting HelpText and display Left stick to move, A to jump .

ResumeButton's On Clicked goes in this order.
- Remove From Parent (Target=self)
- Set Input Mode Game Only (Player Controller Get Owning Player, Flush Input on)
- Set Show Mouse Cursor=false (Target the same Get Owning Player)
Removing the screen alone leaves input directed at the UI. Connect all the way through Game Only, back to controlling the character.

Hands-On: complete a loop with the pad alone
Compile and save everything, then click the Play screen. From here, try it without touching the mouse.
- Walk with the left stick and confirm input stops when you let go
- Press A to jump and land
- Press Menu/Start. A focus frame is on "Resume"
- Press D-pad down to move to "Controls" and confirm with A
- The control explanation appears. The character does not jump behind the menu
- Press D-pad up back to "Resume" and confirm with A
- The screen closes and you can walk again with the left stick

We use normal UMG Buttons and Windows' default UI navigation here. There is no need to add menu logic to IA_PracticeJump to handle UI confirmation.
The M key also opens it, and the same two buttons work with arrow keys and Enter or mouse clicks. After switching to the pad, confirm the original keyboard controls still work.
Check the current input method with Common Input
Playing with a pad while the screen still says "M for menu" leaves you guessing which button. Switching the display connects logic that checks the input method with logic that updates the display.
The Common Input Subsystem is the entry point for the input method in use by that player. It comes from the Common UI plugin. Without preparing icons first, print the method's name with Print String and confirm.
Display the current method once
Stop Play, enable Common UI under "Edit → Plugins", save assets, and restart the editor.
In BP_InputPractice, place Get CommonInputSubsystem from Get Player Controller (0) and promote its output to a variable CommonInputRef . Connect Set CommonInputRef to the end of BeginPlay's existing setup logic.

Create a function PrintInputMethod with no inputs or outputs. Place Get Current Input Type from Get CommonInputRef, convert the returned Enum to a String, and pass it into Print String's In String. Wire the white line from the function entry into Print String with Duration 2.
An Enum is a value representing one of a fixed set of options. The main options here are MouseAndKeyboard, Gamepad, and Touch. Get Current Input Type reads a value, so no white line passes through it.

Place an Is Valid after Set CommonInputRef to check the variable and call PrintInputMethod from the Is Valid side. The Is Not Valid side ends with a Print String saying Common Input unavailable .
Display it when it changes too
Create Bind Event to On Input Method Changed from Get CommonInputRef. Rearrange the Is Valid side into Bind → PrintInputMethod.

From the Bind's Event pin, create the corresponding Custom Event and name it HandleInputMethodChanged . The delegate passed by the red line specifies the event to call when the notification arrives. Call PrintInputMethod from that event's white output. The notification carries the new method's value too, but we reread the current value with the same function as the first pass.

Bind registers "call this logic when something changes". Displaying both the first time and after a change avoids showing nothing until the input method changes.
Save and Play, then press a key and afterwards use the pad. Compare the display when you move the mouse too. Confirm that the method changes according to actual use rather than merely plugging in or holding a pad.
Because mechanisms exist to suppress display flicker, not every physical input necessarily produces an immediate switch notification. To swap button art, set text or images matching the method into a Widget in place of this Print.
What we use here is retrieving the input method and its notification. To build screen hierarchies and confirm/back handling with Common UI, continue to the official Common UI guide, including Viewport and input data settings.
Checks for when it does not work
| Symptom | Where to check |
|---|---|
| The pad does not respond at all | Whether the OS recognizes it, whether the Play screen has input, whether IMC_PlayerControls is active |
| It only responds when the stick is clicked | Whether the key is Gamepad Left Thumbstick 2D-Axis and not the click button |
| It moves after letting go of the stick | Whether the IA value lingers. Whether the Dead Zone is on the stick row and Lower suits your pad |
| A slight tilt does nothing | Whether Lower is too high. Whether a Dead Zone is stacked on both the IA and the IMC |
| A rebinding registration error appears | Whether the added pad Jump row is Ignore Settings. Whether you changed the keyboard's JumpKey |
| The trigger value is only 0 or 1 | Whether the IA is Axis1D and the key is Right Trigger Axis |
| The menu appears but nothing selects | The buttons' Is Focusable, FocusFirstButton after display, Set User Focus's Target and Controller |
| You cannot walk after closing | Whether you return to Game Only. Whether it ends at removing the screen |
| Common Input is not found | Whether you enabled the plugin and restarted. Whether you get it from Get Player Controller |
Bonus: how to think about broadening support
Tidy where focus moves
Extending from two buttons to a settings screen or scrolling list also means deciding "where does pressing right go" and "where does it return after closing". UI focus management continues into specifying Navigation.
To stop game time too, combine with a pause menu. What matters is restoring the display, the input destination, and game time individually.
Separate button position from the printed letter
Gamepad Face Button Bottom represents the position of the bottom face button. We use Xbox-style A as the example, but which letter to display and confirm conventions differ by model and platform.
Knowing the pad's input method and preparing icons matching that model are also separate tasks. Decide your target platforms and match display and behavior on the pads you actually use.
Pad rebinding, and two-player play
To make pad buttons rebindable too, use a registration name separate from the keyboard-only JumpKey, or select the rebinding target including Slot and device. Our Ignore Settings is a choice for keeping this first exercise on a single keyboard slot.
Playing with two pads is covered in split-screen local multiplayer. Before extending to per-player Controllers and input destinations, confirm one player's controls end to end.
Summary
Pad support means adding entry points to the same Input Action, then tidying the stick's small inputs and the UI's selection.
Beyond walking, trying letting go, opening the menu, selecting, closing, and walking again makes it easier to find where control breaks down. Start by building this loop on the one pad you have.
Reference: Enhanced Input, Dead Zone, Pressed, Set User Focus, Common Input Subsystem, Common UI quickstart guide.