Widget Interaction Component¶
A Widget Interaction Component is a virtual pointer for world widgets. It traces for Widget Components, updates hover/focus state, and can simulate the same key or pointer events a viewport button would receive.
At a glance
Use this for: VR lasers, 3D terminals, cockpit buttons, controller
pointers, center-screen interaction with world widgets -
Lives on: a pawn, controller-owned actor, hand/controller component, or
other local input source -
Targets: WidgetComponent surfaces, not ordinary screen HUD widgets -
Returns: most input simulation calls return no success value; query
hover/hit state separately -
Official docs: Widget Interaction Components
and UWidgetInteractionComponent
The one-minute version¶
- The component performs a hit test for world widgets and tells Slate/UMG "this virtual user/pointer is hovering here."
- It does not press buttons automatically. Your input event calls
Press Pointer Key,Release Pointer Key,Press Key,Send Key Char, or scroll functions. Interaction Sourcedecides where the trace comes from: the component's world transform, mouse, center screen, or a custom hit result you provide.Interaction Distanceis just the trace range. It is not gameplay authority, not line-of-sight validation for using the machine, and not a server RPC.- Use unique
Virtual User IndexandPointer Indexvalues when more than one pointer can interact at the same time. - In multiplayer, widget interaction is local input/presentation. The server still validates gameplay requests that the clicked widget sends.
What it actually does¶
The component is a bridge between a world hit and the UMG input system.
pseudocode of the relationship - not engine source
Tick or hit-test update:
trace from the configured source
if trace hits a WidgetComponent:
convert world hit to widget local position
update hover path for VirtualUserIndex / PointerIndex
else:
clear hovered widget path
Input action:
Interact Started -> Press Pointer Key(Left Mouse Button)
Interact Completed -> Release Pointer Key(Left Mouse Button)
The button inside the widget then receives familiar widget events such as
OnHovered, OnPressed, OnReleased, or OnClicked, depending on what you
simulate and what the widget supports.
Where it should live¶
Put the interaction component on the thing that represents the local pointer:
| Feature | Good home |
|---|---|
| VR hand laser | Motion-controller hand actor/component. |
| First-person center-screen terminal use | Player character, camera child, or controller-owned interaction actor. |
| Gamepad cursor | PlayerController or local pointer actor that follows camera/aim. |
| Split-screen local players | Each local player's pawn/controller path, with distinct virtual user/pointer setup. |
| Remote multiplayer player pressing a terminal | The remote player has their own local interaction component on their machine; the server validates the requested action separately. |
Do not put one global Widget Interaction Component in the level and hope it serves every player. The pointer belongs to a local input source.
Interaction Source¶
The source setting changes how the component gets a target:
| Source | Meaning | Use when |
|---|---|---|
| World | Trace from the component's world location and forward direction. | VR lasers, hand pointers, diegetic tools, actor-mounted pointers. |
| Mouse | Use the mouse position for the first local player. | Desktop world-widget experiments or mouse-driven in-world UI. |
| Center Screen | Trace from the center of the local player's view. | First-person "look at panel and press Use" interactions. |
| Custom | Use a hit result you provide with Set Custom Hit Result. |
You already ran a project-specific trace and want Widget Interaction to consume that result. |
Custom is useful when your project has its own interaction trace that filters blocked targets, range, teams, or "can use this now" logic before the UI system gets involved.
Presses, releases, characters, and scroll¶
For buttons, simulate pointer press and release:
Input Interact Started
-> WidgetInteraction.PressPointerKey(LeftMouseButton)
Input Interact Completed
-> WidgetInteraction.ReleasePointerKey(LeftMouseButton)
For text entry, keyboard-style key presses are not always enough. Text boxes
often care about character input, so Send Key Char is the tool that sends
typed characters.
Virtual keyboard key "A" clicked
-> WidgetInteraction.SendKeyChar("A", bRepeat = false)
For scrollable world panels:
MouseWheel / gamepad shoulder
-> WidgetInteraction.ScrollWheel(+1 or -1)
The component simulates input. It does not decide what a clicked button should do.
Hover, focus, and pointer indices¶
World widgets use Slate's virtual-user model under the hood. Beginner meaning: if two pointers exist, they need different identities or they fight over hover and focus.
Use distinct values for cases like:
- left and right VR hands;
- split-screen local players;
- two virtual cursors in one local session;
- a pointer and a virtual keyboard that should not share hover behavior.
On Hovered Widget Changed tells you when the hovered Widget Component changes.
It does not hand you a specific inner button widget as gameplay data. Treat it
as hover presentation/debug context, not as the source of the gameplay action.
Debugging the hit¶
Turn on Show Debug while building. It draws the trace and hit sphere so you
can answer the first question: "Is the pointer actually reaching the widget
component?"
Then debug in this order:
1. Is the trace line hitting the WidgetComponent?
2. Is the WidgetComponent in World space and visible/hit-testable?
3. Is the widget's visibility hit-testable?
4. Are you pressing and releasing the same pointer key?
5. Does the button receive OnPressed / OnClicked?
6. Does the button request gameplay work through the right owner/server path?
If hover works but clicks do not, look at press/release wiring and widget visibility. If clicks work locally but not in multiplayer gameplay, look at the server request path after the widget event.
Multiplayer boundary¶
Widget Interaction Component is local input. A world button click in multiplayer should usually become:
Owning client:
Widget Interaction presses a button on local widget copy
-> widget calls UseTerminalRequested dispatcher
-> owned PlayerController/Pawn sends ServerUseTerminal(TerminalActor)
Server:
validates distance, line of sight, ownership/team/rules
changes replicated gameplay state
Clients:
replicated terminal state updates local widgets/materials/sounds
Do not trust "my local pointer hit the widget" as the server's whole validation. The client can request. The server decides.
When it fails, and what failure looks like¶
| Symptom | Likely cause |
|---|---|
| Hover never changes | Trace source points the wrong way, interaction distance is too short, trace channel misses the widget, or hit testing is disabled. |
| Hover works but click does not | You never call press/release, use the wrong key, release without a press, or the widget is not hit-test visible/enabled. |
| Button stays pressed | Press ran but release did not, often because input completed/canceled was not wired. |
| Text box ignores letters | You sent key presses but not character input; use Send Key Char for typed text. |
| Two hands steal hover from each other | Virtual user or pointer indices are reused. |
| Works in viewport UI but not world UI | Normal mouse clicks hit screen widgets; world widgets need Widget Interaction or hardware input setup. |
| Dedicated server logs warnings or does nothing | The component needs local Slate/UI context; do not run UI input simulation on a server-only path. |
| Multiplayer button appears to work only for the caller | The widget event was local, but no server RPC changed authoritative state. |
What Widget Interaction does not do¶
- It does not create the world widget. That is the Widget Component.
- It does not click buttons automatically because a hit exists.
- It does not make a widget visible, enabled, focusable, or hit-testable.
- It does not validate gameplay use rules.
- It does not replicate button clicks.
- It does not replace normal viewport UI input for menus and HUD buttons.
- It does not guarantee a specific inner widget from
On Hovered Widget Changed; use widget events for actual button actions.
Lookalikes - which one do I want?¶
| Tool | Use when | Watch out |
|---|---|---|
| Widget Interaction Component | A local pointer needs to hover/click a Widget Component in the world. | Simulates UI input only; gameplay still needs authority. |
| Normal viewport mouse/button input | The widget was added to the viewport or player screen. | Does not automatically hit 3D widgets. |
| Line Trace By Channel | You need gameplay hit detection, prompt targets, or server validation. | It does not simulate UMG hover/clicks by itself. |
Blueprint Interface Interact message |
A target actor should respond to a use request. | It is gameplay communication, not widget pointer input. |
| Set Input Mode / Show Mouse Cursor | Menus need local input focus/cursor behavior. | It does not create a 3D pointer trace. |
Rule of thumb: Widget Interaction is for local UMG input against world-widget surfaces; gameplay interaction still travels through your normal interaction request path.
Going deeper¶
- Widget Component and World-Space Widgets - the world UI surface this component points at.
- Crosshair, reticle, and interaction prompts - deciding when a trace should show "Press E" instead of click a world widget.
- Line Trace By Channel - the gameplay trace pattern used for validation or custom hit results.
- Set Input Mode & Show Mouse Cursor - viewport UI input routing.
- Blueprint Custom Events as RPCs - turning a local widget click into a server request when gameplay changes.
- Official docs: Widget Interaction Components, UWidgetInteractionComponent, and Press Pointer Key.
- Engine source (requires engine access - we do not reproduce it here):
UWidgetInteractionComponentis declared inEngine/Source/Runtime/UMG/Public/Components/WidgetInteractionComponent.h; trace, hover, key, pointer, and scroll simulation are implemented inEngine/Source/Runtime/UMG/Private/Components/WidgetInteractionComponent.cpp.