Lesson 9 gave you BP_MissionDirector with dispatchers and phase logic. This lesson finally lets the player see that truth: objective text, detection or suspicion, and setback cues that use the same numbers the AI reads—not a second, drifting copy.

Course illustration - Sleeping Fish pixel art from Dribbble


Lesson objective

By the end of this lesson you will have:

  1. A WBP_StealthHUD (or nested widgets) added to the viewport from your player controller or pawn on begin play.
  2. Bindings from BP_MissionDirector events to objective lines and optional secondary state.
  3. A detection meter (progress bar, material parameter, or simple fill) driven from one replicated-friendly value (stimulus, alert tier, or custom 0–1) that ramps with suspicion and drops on cooldown—matching Lesson 5–7 tuning.

Step 1: Confirm the single source of truth

Before placing widgets, list what the HUD may never invent on its own:

UI element Authoritative source
Primary / secondary text BP_MissionDirector (or subsystem you used in Lesson 9)
Mission phase / setback banner Same director
Detection fill Perception interface, alert enum, or custom float you already log for AI

If you duplicate “suspicion” in the widget with a second timeline, you will ship lies (“HUD says clear, guard is hunting”). Read the same variable or event the Behavior Tree uses for search or engaged.


Step 2: Create the HUD widget

  1. Add User Widget WBP_StealthHUD.
  2. Root with a canvas or overlay; pin safe zones (anchors inset ~4–6% from edges) for TV and ultrawide crops.
  3. Minimum blocks:
    • ObjectiveTitle (Text)
    • ObjectiveBody (Text, smaller)
    • DetectionBar (Progress Bar)
    • StateBanner (Text, optional—for Setback, Detected, Checkpoint)

Pro tip: keep fonts to two weights; stealth readability beats decoration.


Step 3: Spawn the HUD once

In BP_StealthPlayerController (or your controller of choice):

  1. On BeginPlay, Get Actor of ClassBP_MissionDirector → store reference.
  2. Create Widget WBP_StealthHUDAdd to Viewport (Z-order above world, below pause menu).
  3. Pass MissionDirector reference to the widget (expose variable on widget, set right after create).

If you use multiple local players later, gate create with Is Locally Controlled checks.


Step 4: Bind objective dispatchers

On WBP_StealthHUD Event Construct (or a custom Initialize event):

  1. Bind to OnObjectiveChanged (or the custom events you added in Lesson 9).
  2. On fire, set ObjectiveTitle / ObjectiveBody from payload (struct, tags, or parallel string vars on the director).
  3. When primary completes, optionally pulse opacity or play a short animation—under 0.3 s so it does not mask gameplay.

If you did not add dispatchers yet, add them now on BP_MissionDirector and call them from RegisterPrimaryComplete, ApplySetback, etc.


Step 5: Drive the detection meter

Pick one pipeline that matches your Lesson 5–7 setup:

  • Option A — Stimulus magnitude: map hearing + sight contributions to a 0–1 float each tick or on perception update; lerp the bar toward that target.
  • Option B — Alert enum: Idle = 0, Suspicious = 0.33, Investigate = 0.66, Engaged = 1.0 with lerp down on lost sight timers.

Expose SetDetectionNormalized(float) on the widget. The player or a small UI bridge Blueprint reads perception from the focused guard or an aggregated “worst case” value—whatever you documented in Lesson 7.

Critical: clamp and smooth. Raw perception spikes every frame look like broken UI.


Step 6: Accessibility and contrast

Stealth games fail players when red = danger is the only channel.

  • Add a secondary cue: icon, thickness, or pulse rate on the bar—not color alone.
  • Test ObjectiveBody on snow and cave shots; add a thin dark plate behind text if needed.
  • Offer a UI_HighContrast bool on the director or settings save; swap text and bar styles (higher stroke, simpler gradients).

Our accessibility plugins and checklists resource is engine-mixed but the rubric (contrast, motion, remapping) still applies to UMG planning.


Step 7: Pause, death, and setback layering

  • When pause opens, remove or hide gameplay HUD—or lower opacity so menu reads first.
  • Setback (Lesson 9) should trigger a short banner + optional bar flash using the same ApplySetback path—no duplicate timer in the widget.

Mini challenge

  1. Force primary complete in PIE—confirm title updates once (no double bind).
  2. Walk into sight until investigate—bar should rise and fall on cooldown with no desync versus guard anim.
  3. Trigger checkpoint—HUD should not reset objective text unless the director fires a refresh event.

Troubleshooting

Symptom Likely cause Fix
Bar stuck at full No decay / wrong enum Add lerp to zero on lost contact; verify update path
Objectives blank Director not found Delay bind one tick; validate reference on HUD construct
Double text updates Bound twice Unbind before rebind or guard with bool
Widget ignores input Focus / hit test Disable hit testing on HUD root if clicks should pass through

Summary

  • One authority for mission strings; one pipeline for threat readout.
  • UMG is view—not a second game loop.
  • Accessibility is layout + motion, not a post-launch patch.

Further reading


FAQ

Widget in world space for diegetic UI?
Possible for markers; for slice scope, screen HUD is faster to ship.

Multiplayer?
Replicate director phase and detection tier on server; HUD reads replicated vars.


Next: Lesson 11: Audio Stealth Mix and Spatial Cues covers footsteps, occlusion, and stingers tied to alert changes. Finish Lesson 10 when your HUD survives a five-minute PIE session with no stale objective text after checkpoint restore.