Course contentsShow
← Unreal Engine Game Development
Lesson 569 of 8808. User Interface and MetaSoundsFree lesson

Handling Input Routing and Focus Management

Configure input propagation and focus traversal rules to ensure your custom widgets correctly handle mouse, keyboard, and gamepad interactions.

In this lesson, you will learn how to configure input propagation and focus traversal rules to ensure your custom widgets reliably intercept and process user interactions.

Understanding Input Routing

When a user clicks or presses a key, Slate doesn't just "know" which widget to trigger. It follows an Input Routing process, traversing the widget hierarchy from the top-most visual layer down to the underlying elements. If a widget’s OnMouseButtonDown function returns FReply::Unhandled(), the input continues to propagate to the parent or widgets behind it. To "capture" the input, you must return FReply::Handled(), which stops the event from bubbling further.

Managing Focus Traversal

Focus is the primary mechanism for keyboard and gamepad navigation. When a widget has focus, it becomes the target for all non-mouse inputs. You manage this using the bIsFocusable property and the GetNavigationAction override.

If you are building a custom UI panel, you should define how focus moves when the user presses a directional key. You can explicitly set navigation rules in your widget’s construct or via the FNavigationReply struct.

For example, to ensure your custom widget captures focus on click, your OnMouseButtonDown should look like this:

FReply SMyCustomWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
    // Capture focus so keyboard navigation works
    return FReply::Handled().SetUserFocus(SharedThis(this), EFocusCause::Mouse);
}

Designing for Interaction

When designing custom widgets, always consider the Visibility setting. A widget with Visibility::HitTestInvisible will be rendered but effectively ignored by the input routing system, allowing clicks to pass through to widgets beneath it. Conversely, Visibility::Visible acts as a wall that consumes input. By strategically toggling these settings and returning the correct FReply state, you create a responsive UI that prevents "input bleed," where a button click accidentally triggers gameplay actions instead of a menu selection.

Key Takeaway: Precise input control requires returning the appropriate FReply state to stop event propagation and explicitly setting focus to ensure your widgets remain the intended target for navigation inputs.