HUD and Input Prompts

Documentation Unreal Engine Player Combat UI Input

Build a HUD that follows the character: bars and markers that show with the combat style, cooldowns and held states from the ability system, and button prompts that show the key the player has bound.


Set it up

10 minutes
  1. 1

    Make the HUD a listener widget

    Create a Widget Blueprint, WBP_MyHUD. In its Graph view, open Class Settings and set Parent Class to UPC Ability System Listener Widget.
  2. 2

    Add a stamina bar that shows by style

    Add a Progress Bar named StaminaBar and bind Percent to Get Vital Fraction on the pawn's UPC Vitals with Vital Tag UPC.Vital.Stamina (BP_UPC_Character has the row; yours needs one, see Vitals). In Class Defaults, add a Show While Tagged row for the bar.
    WBP_MyHUD
    ▾Show While Tagged
    StaminaBar 
    The bar shows only while the character carries the tag: in the demo's Over Shoulder and Soulslike styles, not Freeflow.
  3. 3

    Point the HUD at the character

    In your player controller, on Begin Play when Is Local Controller, Create Widget WBP_MyHUD, store it and Add to Viewport. From On Possessed Pawn Changed, call Initialize for Actor with New Pawn (unless none), so a respawn rebinds the HUD; for an already held pawn, call it once with Get Controlled Pawn.
    BP_MyPlayerController · Event Graph
    Bind Event to On Possessed Pawn Changed
    Target is Controller
    Targetself
    Event
    OnPossessedPawnChanged_Event
    Custom Event
    Old Pawn
    New Pawn
    HUD
    Initialize for Actor
    Target is UPC Ability System Listener Widget
    Target
    Actor
  4. 4

    Add a key prompt

    Create WBP_AttackPrompt with parent UPC Input Glyph Widget, an Image, a Text Block and Input Tag UPC.Input.LightAttack. In On Glyph Resolved, hide the prompt while Resolved or Matched Device Family is false; feed Icon to the Image's Set Brush from Soft Texture when Has Icon, else show Short Label. Place it in WBP_MyHUD and press Play: it shows light attack's key once a drawn weapon maps it. Keys come from a UPC Input Mapping component on the pawn or controller (BP_UPC_Character has one; Input).

Show parts of the HUD by combat style

A Show While Tagged row pairs a widget with the tag that shows it (a child tag counts). The widget collapses while the character lacks the tag and returns as it was. A widget inside a child widget takes a dotted path (Vitals.StaminaBar). The combat style's Gameplay Tags fragment applies the tags (Combat Styles), so each style decides what its HUD shows.
TagShowsDemo styles carrying it
UPC.UI.Show.StaminaThe stamina barOver Shoulder, Soulslike
UPC.UI.Show.StanceThe stance barSoulslike
UPC.UI.Show.BeltThe beltOver Shoulder, Soulslike
UPC.UI.Show.CooldownsAbility cooldownsOver Shoulder, Soulslike
UPC.UI.Show.CrosshairAn aiming crosshairOver Shoulder
UPC.UI.Show.LockOnA lock-on markerOver Shoulder, Soulslike

React to cooldowns and states

Listen Root Tags lists the parent tags to report. A gameplay effect (timed buff, cooldown) or a plain tag set directly on the character under one of them fires two events; states already running report as the widget starts listening.
EventFires
On State StartedA state began, or another effect with its tag arrived: add or update its element. Time Remaining and Total Duration read 0 with no timer. Magnitude is the effect's value under Magnitude Set by Caller Tag, else 0.
On State EndedThe last source went (effect ended or tag removed): remove its element.
Get State Time Remaining and Is State Active answer for one tag any time. An Instant effect reports nothing (see Multiplayer below); give a state you want on screen a duration, or hold a plain tag.

Two displays the demo builds

Each is a listener widget with its own Listen Root Tags: WBP_UPC_AbilityCooldownStack and WBP_UPC_Crosshair (Demo/UI/Widgets/HUD). Initializing the HUD does not reach a listener inside it: call Initialize for Actor on each from the HUD's graph with the same pawn.
Cooldowns. Take a dodge on a 1.5 second cooldown. Set Listen Root Tags to UPC.Cooldown and Magnitude Set by Caller Tag to UPC.SetByCaller.Cooldown, where a Cooldown gate writes its length (Gates, Costs and Cooldowns covers gate and charges). For a tag under UPC.Cooldown (UPC.Cooldown.Ability.Dodge), On State Started reports the longest running use's timer and the length in seconds as Magnitude.
To draw it, add or update an icon for State Tag in On State Started and remove it in On State Ended. With Total Duration above 0, count down from Time Remaining over Total Duration; otherwise from Magnitude to 0 over Magnitude seconds, so a bar starts full and empties. Until the server's timer arrives the player's machine reads Time Remaining and Total Duration as 0, so the dodge fires On State Started twice there:
UpdateTime RemainingTotal DurationMagnitudeDo
First001.5Count down from Magnitude: fraction 1 to 0 over 1.5 seconds.
When the server's timer arrivesThe real remainderThe real length1.5Continue from these.
Details
WBP_MyCooldowns
UPC
Ability System Listener
Listen Root Tags
1 Gameplay Tag
UPC.Cooldown
Magnitude Set by Caller Tag
UPC.SetByCaller.Cooldown
A listener widget inside the HUD, listening for cooldowns: effects under UPC.Cooldown reach On State Started, each with its length as Magnitude.
A hit marker. On its own listener widget, set Listen Root Tags to UPC.UI.Crosshair and UPC.State.LockedOn. Each melee hit on a target that takes it holds UPC.UI.Crosshair.Hit on the player for 0.1 s (a start, then an end): flash the marker (Server Authoritative detection: see What runs where). UPC.State.LockedOn holds while the player holds a lock.

Show the key for an input

Give a UPC Input Glyph Widget an Input Tag (UPC.Input.Interact) or an Input Action (wins over the tag). On Glyph Resolved fires whenever the answer changes, so no Tick is needed. Set Input Tag and Set Input Action repoint it; call Refresh Glyph after a change only your game knows about.
Glyph fieldHolds
ResolvedFalse when nothing is bound: hide the prompt.
KeyThe key the player presses.
Icon, Has IconKey art from a glyph set; without it show Short Label.
Short Label, Long LabelKey text from the glyph set, else the engine's names.
Matched Device FamilyFalse when the input has no key on the device in use and Key is another device's: hide the prompt.
Key TakenTrue while the device's key presses something else (an open screen's control): dim the prompt.

Give the keys artwork

An Input Glyph Set is a sheet of key art for one Device Family; Unspecified serves every device, and Hardware Device Identifiers, such as DualSense, keep it to those pads. Each Glyphs row gives a key an Icon, a Short Label of one or two characters and a Long Label for a rebinding screen; an empty label falls back to the engine's name for the key.
Content Browser
▸ Content
Details
InputGlyphSet_MyPlayStation
UPC
Input Display
Device Family
Gamepad
Hardware Device Identifiers
3 Array elements
Index [ 0 ]
DualSense
Index [ 1 ]
DualSenseEdge
Index [ 2 ]
DualShock4
Glyphs
4 Array elements
Gamepad_FaceButton_Bottom
Key
Gamepad Face Button Bottom
Icon
T_UPC_UI_Gamepad_Cross
Short Label
Long Label
Gamepad_FaceButton_Right
Icon
T_UPC_UI_Gamepad_Circle
Gamepad_FaceButton_Left
Icon
T_UPC_UI_Gamepad_Square
Gamepad_FaceButton_Top
Icon
T_UPC_UI_Gamepad_Triangle
A sheet for PlayStation pads: it applies while the pad in use reports one of these names. Each face button draws its icon, the labels stay empty so they fall back to the engine's names, and every other key falls through to the next sheet in the list.
List it under Glyph Sets in Project Settings > Plugins > Universal Player Combat Input Display, above the plugin's sheets. The first sheet serving the player's device that lists the key wins. The list ships with the plugin's sheets in Content/Core/Inputs, which stay when you remove the demo: PlayStation (DualSense, DualSense Edge, DualShock 4), a generic gamepad sheet for every other pad, and keyboard. With no sheet, prompts show the engine's key names.
Details
Universal Player Combat Input Display
Glyph Sets
Glyph Sets
4 Array elements
Index [ 0 ]
InputGlyphSet_MyPlayStation
Index [ 1 ]
InputGlyphSet_UPC_PlayStation
Index [ 2 ]
InputGlyphSet_UPC_Gamepad
Index [ 3 ]
InputGlyphSet_UPC_Keyboard
Fallback
Default Device Family
Keyboard Mouse
Warn on Unbound Input
Device Detection
Device Switch Analog Dead Zone
0.20
InputGlyphSet_MyPlayStation sits above the plugin's three sheets, so its face buttons win on the pads it names.
SettingDoes
Default Device FamilyDevice assumed until the player uses one (Keyboard Mouse).
Warn on Unbound InputWarns once when an input tag has no Input Action, or the player has no UPC Input Mapping component. Turn off for inputs left unbound on purpose.
Device Switch Analog Dead ZoneStick or trigger travel, 0.05 to 1 (default 0.2), before prompts switch to the gamepad; raise for a drifting stick.

A panel of control hints

PieceDoes
UPC Input Hint SetData asset (right-click, UPC, Presentation, Input Hint Set): a Title and ordered Hints, each an Input Action or Input Tag, a Label ("Open"), and Hide when Unbound.
UPC Input Hint WidgetOne row. Reparent a Widget Blueprint to it; implement On Glyph Resolved (key) and On Hint Changed (label).
UPC Input Hint List WidgetThe panel. Reparent a Widget Blueprint to it, add a panel named HintList (a Vertical Box works) and set Row Class. Default Hint Set shows at start, Set Hint Set swaps rows, On Hint Set Changed shows the Title.
A row with Hide when Unbound on (default) collapses while the device has no key for its input (a gamepad-only input on a keyboard). A row whose key an open screen took, or one with Hide when Unbound off and no key, fades in place, keeping its key, size and position. Unavailable Opacity (0.4) scales its opacity while faded; 1 turns the fade off.

Debug it

The listener logs under LogUPCUI, prompts under LogUPCInput.
AdvancedHow states are counted
  • Initialize for Actor also finds an ability system on the PlayerState. Called again, it ends every on-screen state, then reports the new system's. Initialize for Ability System with None stops listening, ends every state, collapses the Show While Tagged widgets and warns.
  • Show While Tagged widgets stay collapsed until the widget listens; call Refresh Tagged Visibility after changing the table at runtime.
  • Effects sharing a tag count as one state with the longest time (no timer if any has no duration); a tag held by an effect and as a plain tag follows the effect.
  • An effect counts through its asset and granted tags (runtime ones included), reporting the first under a root; a plain tag counts only as that exact tag. A stack added to a running effect fires nothing.
AdvancedHow a prompt finds its key
An input tag, such as UPC.Input.LightAttackWhat On Glyph Resolved receives
1
The inputs the character carries
UPC Input Mapping on the pawn, else on its controller
Everything registered there counts: the component's own Input Mappings, a drawn item's mappings and a granted ability set's keys. With no such component, every prompt shows no key, and the log says so while Warn on Unbound Input is on.
2
The Input Action behind the tag
every mapping whose Input Tag is the prompt's
With several, the first whose keys include one for the device the player is using. With none, the glyph comes back with Resolved false, the cue for the prompt to hide.
3
The key
the keys the active mapping contexts map to that action
The first key belonging to the device in use, else the first key at all, which reports Matched Device Family false so the prompt can hide it. A device key that other controls have taken, such as an open screen's, still resolves and reports Key Taken, so the prompt can dim it. An action no context maps reports nothing bound.
4
The artwork
Glyph Sets in Project Settings, top to bottom
The first sheet serving the device that lists the key gives the Icon and labels. A key no sheet lists still resolves, with the engine's short name for it as Short Label and its full name as Long Label.
The answer is worked out again on its own when the player switches device, a key is rebound, a mapping context goes on or off (drawing or stowing an item that brings one does this), or the player's controller changes.
  • The device is the last used on purpose: a key or button, a stick or trigger past the dead zone, 2 pixels of mouse travel, a touch. In the editor, keyboard, mouse and touch count only inside that player's viewport.
  • With several actions on a tag, a prompt takes the one the device can press, then one whose key another control took, then any. Covered by Glyph Set says a sheet listed the key; Device Family names the device the answer is for.
  • Hardware Device Identifiers match the platform's name for the pad (Get Current Controller Brand). An Xbox pad, and any pad Steam Input or a remapping tool presents as one, reports XInputController and reads the generic sheet; add the name your setup reports to a sheet's identifiers to change that.
AdvancedPrompts without the widget base
Get UPC Input Display, fed Get Owning Player, returns the player's input display:
NodeDoes
Resolve Input Glyph, Resolve Glyph for ActionThe glyph for an input tag or an Input Action.
Resolve Glyph for KeyThe icon and labels for one key, for a rebinding row.
Get Current Device Family, Get Current Controller BrandLast device used (never Unspecified); the platform's name for the last controller (empty until one is used).
On Input Glyphs ChangedA prompt's answer may have moved: ask again.
On Input Device Family ChangedThe kind of device changed.
Find Glyph for Key reads one glyph set's row.
The demo
  • WBP_UPC_HUD (Demo/UI/Widgets/HUD) is the demo HUD, created by BP_UPC_PlayerController.
  • Demo/Showcase/UI: WBP_UPC_KeyHint (row), WBP_UPC_ShowcaseHints (panel), BP_UPC_HintZone (box showing its hint set while the player stands inside); hint sets in Demo/UI/Hints.
MultiplayerWhat runs where
  • The HUD reads its own machine's ability system: a predicted effect shows at once, a refused one ends through On State Ended, and a predicted Instant effect can flash as a start and an end.
  • A loose tag added only on the server never reaches a player's HUD; keep the Gameplay Tags fragment's Scope reaching the player's machine.
  • The hit marker flashes on the attacker's machine as the swing connects, even for a hit the server then drops. Under Server Authoritative hit detection that machine finds no hits, so draw the marker from a gameplay cue on the damage config's Attacker Cues that checks Is Attacker Locally Viewed.
  • Prompts live on the local player and replicate nothing. Each split-screen player gets their own device's keys.
C++C++
  • UUPCAbilitySystemListenerWidget binds the ability system's effect added and removed delegates and its generic tag event; OnStateStarted and OnStateEnded are Blueprint events.
  • UUPCInputGlyphWidget::NativeOnGlyphResolved runs before the Blueprint event; UUPCInputHintWidget collapses or fades its row there.
  • UUPCInputDisplaySubsystem is a local player subsystem: GetForPlayer returns it, ReportDeliberateInput(Family, DeviceId) switches the family for a game tracking devices itself, and the statics KeyBelongsToFamily, ClassifyKey, PickKeyForFamily and ResolveGlyphFromSets run the rules above. A prompt reads UUPCInputMappingComponent::FindFor and GetInputActionsForTag (Input).
AdvancedTroubleshooting
Warning or symptomFix
...initialized against an actor with no ability systemCall Initialize for Actor once the pawn is possessed; for an ability system on the PlayerState, after possession settles.
...Listen Root Tags list and its Show While Tagged table are both emptyFill one.
Show While Tagged names '...', which this widget does not containFix the name, or use a dotted path.
No Input Action is bound to '...'Map an Input Action to the tag, or turn off Warn on Unbound Input.
No UPC Input Mapping component is on this player's pawn or controllerAdd one (Input). A prompt built before possession logs it once and recovers.
The glyph sheet ... does not existRemove it from Glyph Sets.
A PlayStation pad shows A and LBIt reports as an Xbox pad: see How a prompt finds its key.