How-To: World Indicators & Hold-Progress Feedback

Goal: give the player feedback - on the target itself, on the HUD, and (if your project can use CrimsonCore) as floating world indicators.

1. Per-target progress (no dependencies)

During a hold or channel, the interactor pushes normalized progress to the target via NotifyInteractionProgress (0 on cancel/release, 1 on completion) - an ICrimsonInteractableTarget method with a no-op default. Override it on the interactable to drive a radial fill, material parameter, light glow, anything. No coupling to any plugin.

On the interactable Blueprint: Class Settings -> Details -> Interfaces -> Add -> Crimson Interactable Target (already there if you followed the Quick Start). In My Blueprint -> Interfaces, double-click Notify Interaction Progress.

In the event: Event Notify Interaction Progress -> Set Percent on a ProgressBar inside a widget component, or -> Set Scalar Parameter Value on a dynamic material instance (Parameter Name = Fill, Value = the event's Progress pin). Progress arrives in 0..1, and the interactor pushes 0 on cancel or release and 1 on completion - so a bar driven straight from the pin fills, resets and completes with no extra state of its own.

2. HUD progress via the duration context

Create a UCrimsonInteractionDurationContext in your channel ability on the owning client, give it to your HUD widget, and call UpdateProgress each tick; the widget binds OnProgressChanged. Full snippet in How-To: Add Holds, Channels & a Progress Prompt, step 3. (CrimsonCore - requires all Crimson plugins) also re-publishes progress as a message for any HUD.

3. Floating world indicators (CrimsonCore - requires all Crimson plugins)

If your project has all Crimson plugins installed, CrimsonCore's prebuilt interact ability shows one world indicator per option (PromptMode = WorldIndicator); its indicator manager is added to the local player controller automatically, and the widget class resolves per option (InteractionWidgetClass on the option, else the ability's defaults). Building standalone? Your equivalent is any widget you drive from OnOptionsChanged - the option's InteractionWidgetClass field is yours to interpret (e.g. spawn a UWidgetComponent on the focused target).

Standalone, the indicator is a widget you spawn from the options handler - the same Custom Event that sets CurrentOptions in How-To: Write Your Own Interact Ability step 3 (on Crimson Basic Interact, override Update Interactions instead). In it: Set CurrentOptions -> Length -> Greater (integer) (B = 0) -> Branch. On True: Get CurrentOptions -> Get (a copy) (Index = 0) -> Break CrimsonInteractionOption, then Get Actor From Interactable Target on the broken Interactable Target pin to reach the actor to mark, and Async Load Class Asset on the broken Interaction Widget Class (it is a soft class pointer) -> Create Widget -> Add to Viewport, or feed the loaded class into a WidgetComponent you spawn on that actor for a world-space marker. On False, tear down whatever you spawned.

Interaction Widget Class is a plain data field on the option - this plugin never reads it. Its meaning is whatever your handler decides, which is what lets one interactable ask for a different prompt than another without either of them knowing how prompts are drawn.

CrimsonCore ships this prebuilt
(CrimsonCore - requires all Crimson plugins) CrimsonCore is free to download, but it only compiles when all Crimson plugins are installed. Its prebuilt interact ability does the whole paragraph above for every option at once: set Prompt Mode to World Indicator and give it a Default Indicator Widget Class, and a UCrimsonIndicatorManagerComponent is added to the local player controller for you, with a per-option Interaction Widget Class overriding the default. If your project cannot use it, the standalone path above is the equivalent and needs nothing but this plugin.
Verify
In range, your prompt appears (indicator or HUD). Hold: the target-side bar (step 1) and any HUD listener (step 2) fill together, reset on early release, and complete at 1.0.