Create The Widget Class
Create a UMG widget Blueprint based on UInteractionUIWidgetBase. Assign it in UI developer settings when it should be the default prompt widget, or use a project UI flow that creates and owns the widget directly. The widget base class is the point where runtime prompt state enters the visual layer.
Bundled Demo Widgets
The demo content includes prompt widgets you can inspect or assign directly while learning the plugin. Enable Show Plugin Content to find them under /InteractionFramework/Widgets.
WB_VerticalInteractionListis the regular interaction list example and the best starting point for common command prompts.WBP_InteractionKeyrenders a single command key/prompt row and is used inside the other demo widgets.- The bundled four-option command widget demonstrates a multi-choice custom prompt.
WB_PickUpInteractiondemonstrates a custom pickup prompt selected through a widget payload override.
Widget Event Responsibilities
A prompt widget should respond to state it receives. Handle focus changes, projection bundles, surface entry add/update/remove events, control entries, progress, outcomes, route stage text, paging state, input family, and widget payload changes. Keep each visual state independent so, for example, a cooldown update does not erase participant progress or a route update does not rebuild the whole widget unnecessarily.
Rendering Prompt Entries
Prompt entries are already resolved for the current interactor. Render the supplied command text, input glyph or key text, availability state, failure reason, cooldown text, percent/progress fields, and command id. Do not sort or filter rows in a way that changes command identity; activation requests depend on the runtime surface entry the user selected.
Rendering Input Prompts
For a text-only row, bind FInteractionUIPromptTextPresentation::InputText. For a premium widget that can show glyphs from an entry event, use TryGetInputPromptPresentationFromEntry instead of manually breaking the entry, prompt, text, and input presentation structs. If you already have the prompt text struct, read InputPresentation directly. It carries the resolved key, input family, text fallback, optional texture glyph, optional material glyph, and style name selected from UI developer settings.
Use bHasVisual to choose between icon/material rendering and text fallback. Use OnInputFamilyChanged to refresh cached row visuals when a local player switches between keyboard/mouse and gamepad. The event is per widget instance, so multiple live prompt widgets can each receive it.
Rendering Control Entries
Control entries represent paging, cancellation, or other non-command controls. They should be visually distinct from gameplay commands when the UI style allows it. Use the supplied input action and prompt text instead of creating hard-coded keys in the widget.
Projected Position
Apply projected screen position and clamp data from the widget events or projection bundle. When a point is behind the camera, outside the viewport, or clamped to an edge, render a state that fits your UI style. If the widget shows to chase the wrong location, fix point bindings or projection settings before adding widget-side offsets.
Payload Application
When SetWidgetPayload or the payload change event supplies a UInteractionRuntimeWidgetPayload, cast to the project payload subclass only in the widget layer. Use it for display data such as icon, label, palette, layout mode, or extra text. Runtime command validation remains in requirements, target state, and execution actions.
Release And Pooling
OnWidgetReleaseRequested lets the widget request release back to the manager or pooling layer. Use release for hidden prompts, ended focus, or UI ownership changes. Do not destroy the widget from inside every state update unless your project UI intentionally avoids pooling.
Blueprint Implementation Checklist
- Bind update events once during widget initialization.
- Keep a map from runtime entry id or index to visual row widgets.
- Update rows incrementally when entries change.
- Clear rows when the surface changes or focus ends.
- Render progress, cooldown, route, and failure states as separate layers.
- Use payloads for project visuals, not for server gameplay state.
Widget State Architecture
Separate the widget into small state handlers: projection, surface rows, controls, progress, outcome, route, payload, and release. This makes it possible to update the projected position without rebuilding rows, update a cooldown label without changing layout, and clear route state without destroying the entire widget tree.
Data Binding Pattern
Use a row object or widget per prompt entry. Store the runtime entry identity or surface index, displayed text, input display, enabled/unavailable state, and progress state. When an update event arrives, update the matching row. When a remove event arrives, release that row widget. This keeps UI stable during rapid focus and progress updates.
Polish Checklist
- Rows do not resize unpredictably when text changes.
- Cooldown/progress text has enough room for the longest expected value.
- Behind-camera or clamped prompts use a consistent visual treatment.
- Unavailable commands have readable failure text if the policy exposes it.
- Multi-participant stage and participant counts do not cover command input labels.