Quick answer: The most common cause is that IsFocusable is set to false on the widget. By default, many UMG widgets are not focusable. You must enable IsFocusable in the widget's details panel or set it in code.
Here is how to fix Unreal UMG widget focus not working gamepad. Your UMG menu looks perfect with a mouse. Buttons highlight on hover, clicks register, and navigation feels natural. Then you plug in a gamepad or try to navigate with keyboard arrows and nothing happens. No button highlights, no focus indicator, D-pad input goes nowhere. The UI is completely inert to non-mouse input. This is one of the most common UMG issues in Unreal Engine and it stems from a combination of widget focus settings, input mode configuration, and navigation rules that all need to be correct simultaneously.
The Symptom
You have designed a UMG widget blueprint with buttons, sliders, or other interactive elements. Using a mouse, everything works. Buttons respond to hover and click events. But when you switch to a gamepad controller or try to use keyboard Tab and arrow keys, no widget receives focus. There is no visual focus indicator, pressing A or Enter does not activate any button, and the D-pad does not move between elements.
In some cases, the first button in the menu receives focus when the widget is first shown, but pressing any direction on the D-pad does nothing — focus stays locked on that first button. In other cases, focus jumps unpredictably, skipping buttons or moving in the wrong direction when you press Up or Down on the analog stick.
A particularly frustrating variation occurs when focus works in Play-In-Editor (PIE) mode but breaks in a standalone or packaged build. This usually indicates that the input mode is being set differently depending on the launch context, or that the viewport focus state differs between PIE and standalone.
What Causes This
1. IsFocusable is not enabled on the widgets. By default, most UMG widgets have IsFocusable set to false. This includes UButton widgets created in the designer. A widget that is not focusable will never receive keyboard or gamepad focus, regardless of any other setting. The mouse bypasses the focus system entirely for hover and click events, which is why mouse interaction works even when IsFocusable is off.
2. The input mode is not set to route input to UI. Unreal has three input modes: Game Only, UI Only, and Game and UI. By default, the player controller uses Game Only mode, which sends all input to the game viewport and never to UMG widgets. You must explicitly call SetInputMode_UIOnlyEx or SetInputMode_GameAndUIEx when showing a menu. Without this call, the gamepad D-pad and face buttons are consumed by the game input system and never reach the Slate focus framework.
3. No initial focus is set. Even with IsFocusable enabled and the correct input mode, UMG does not automatically focus the first widget. You must explicitly call SetFocus() or SetUserFocus() on a specific widget after it has been added to the viewport. If no widget has focus, gamepad input has no starting point for navigation and all directional inputs are ignored.
4. Automatic navigation cannot resolve the widget layout. Unreal’s default navigation mode uses widget geometry to determine which widget is “up” or “down” from the current one. If your buttons are arranged in a non-grid layout, overlapping, inside scroll boxes, or positioned with unusual anchors, the automatic navigation may fail to find valid targets. This results in focus being stuck on one widget with no directional movement.
The Fix
Step 1: Enable IsFocusable on all interactive widgets and set the correct input mode. This is the foundational fix. Every button, checkbox, slider, or custom widget that should respond to gamepad input must be marked focusable. Then, configure the player controller to route input to the UI when a menu is visible.
// Menu widget class that handles gamepad focus setup
// Header: UMyMenuWidget.h
UCLASS()
class UMyMenuWidget : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(meta = (BindWidget))
UButton* PlayButton;
UPROPERTY(meta = (BindWidget))
UButton* SettingsButton;
UPROPERTY(meta = (BindWidget))
UButton* QuitButton;
virtual void NativeConstruct() override;
UFUNCTION(BlueprintCallable)
void ShowMenu();
UFUNCTION(BlueprintCallable)
void HideMenu();
};
// Implementation: UMyMenuWidget.cpp
void UMyMenuWidget::NativeConstruct()
{
Super::NativeConstruct();
// Ensure all buttons are focusable
if (PlayButton) PlayButton->SetIsFocusable(true);
if (SettingsButton) SettingsButton->SetIsFocusable(true);
if (QuitButton) QuitButton->SetIsFocusable(true);
UE_LOG(LogTemp, Warning, TEXT("Menu constructed. Buttons focusable."));
}
void UMyMenuWidget::ShowMenu()
{
AddToViewport();
SetVisibility(ESlateVisibility::Visible);
// Set input mode to UI and focus the first button
APlayerController* PC = GetOwningPlayer();
if (PC)
{
FInputModeUIOnly InputMode;
InputMode.SetWidgetToFocus(PlayButton->TakeWidget());
InputMode.SetLockMouseToViewportBehavior(
EMouseLockMode::DoNotLock);
PC->SetInputMode(InputMode);
PC->SetShowMouseCursor(true);
UE_LOG(LogTemp, Warning,
TEXT("Input mode set to UI Only. Focus on PlayButton."));
}
}
Step 2: Set initial focus explicitly after the widget is added to the viewport. Timing matters here. The widget must be fully laid out by Slate before focus can be set. If SetFocus() is called too early, the underlying Slate widget may not exist yet and the call silently fails. Use SetUserFocus() for multiplayer scenarios where you need to specify which player controller receives the focus.
// Robust focus setting with a one-frame delay
// This ensures the Slate widget tree is fully built
void UMyMenuWidget::ShowMenu()
{
AddToViewport();
// Schedule focus for the next frame so Slate layout is complete
GetWorld()->GetTimerManager().SetTimerForNextTick(
[this]()
{
if (!PlayButton) return;
APlayerController* PC = GetOwningPlayer();
if (!PC) return;
// Set input mode with the widget to focus
FInputModeGameAndUI InputMode;
InputMode.SetWidgetToFocus(PlayButton->TakeWidget());
PC->SetInputMode(InputMode);
// Also explicitly set user focus for this controller
PlayButton->SetUserFocus(PC);
UE_LOG(LogTemp, Warning,
TEXT("Focus set on PlayButton for controller %d"),
PC->GetLocalPlayer()->GetControllerId());
});
}
void UMyMenuWidget::HideMenu()
{
RemoveFromParent();
// Restore input mode to Game Only
APlayerController* PC = GetOwningPlayer();
if (PC)
{
FInputModeGameOnly InputMode;
PC->SetInputMode(InputMode);
PC->SetShowMouseCursor(false);
UE_LOG(LogTemp, Warning,
TEXT("Menu hidden. Input mode restored to Game Only."));
}
}
Step 3: Override automatic navigation with explicit rules. If the D-pad moves focus in the wrong direction or skips buttons, override the automatic navigation on each widget. You can do this in the UMG designer’s Navigation panel or in C++ by setting custom navigation rules that explicitly define what happens on each directional input.
// Set explicit navigation between buttons in C++
void UMyMenuWidget::NativeConstruct()
{
Super::NativeConstruct();
// Make all buttons focusable
PlayButton->SetIsFocusable(true);
SettingsButton->SetIsFocusable(true);
QuitButton->SetIsFocusable(true);
// Configure explicit vertical navigation:
// PlayButton <-> SettingsButton <-> QuitButton
// PlayButton: Down goes to Settings, Up wraps to Quit
PlayButton->SetNavigationRuleExplicit(
EUINavigation::Down, SettingsButton);
PlayButton->SetNavigationRuleExplicit(
EUINavigation::Up, QuitButton);
// SettingsButton: Down goes to Quit, Up goes to Play
SettingsButton->SetNavigationRuleExplicit(
EUINavigation::Down, QuitButton);
SettingsButton->SetNavigationRuleExplicit(
EUINavigation::Up, PlayButton);
// QuitButton: Down wraps to Play, Up goes to Settings
QuitButton->SetNavigationRuleExplicit(
EUINavigation::Down, PlayButton);
QuitButton->SetNavigationRuleExplicit(
EUINavigation::Up, SettingsButton);
UE_LOG(LogTemp, Warning,
TEXT("Navigation rules configured. Wrapping enabled."));
}
// Debug helper: log which widget currently has focus
void UMyMenuWidget::NativeTick(
const FGeometry& Geometry, float DeltaTime)
{
Super::NativeTick(Geometry, DeltaTime);
TSharedPtr<SWidget> Focused =
FSlateApplication::Get().GetUserFocusedWidget(0);
if (Focused.IsValid())
{
UE_LOG(LogTemp, Verbose, TEXT("Focused widget: %s"),
*Focused->GetTypeAsString());
}
}
Related Issues
If your gamepad input reaches the UI but button click events do not fire, check our guide on Blueprint events not firing for delegate binding issues with UMG buttons. If you are building a split-screen game and only one player can interact with the UI, the issue is likely related to user focus indices — each local player has a separate Slate user ID and you must call SetUserFocus with the correct player controller.