How-To: UI Extension Points

Goal: carve named slots into your HUD that optional features (GameFeature plugins, DLC, debug tooling) fill with widgets at runtime - the HUD never references the feature.

Prerequisites
Quick Start done. Slot tags defined (e.g. HUD.Slot.Toasts, HUD.Slot.Reticle in your GameplayTags settings - any parent works; HUD.Slot is the CrimsonCore convention). The extension registry (UCrimsonUIExtensionSubsystem) lives in CrimsonCommon.

1. Place an extension point in the HUD

In BP_HUDLayout's Designer add a Crimson UI Extension Point Widget (UCrimsonUIExtensionPointWidget, a dynamic entry box) where the optional content should appear. Set ExtensionPointTag (the slot's tag) and ExtensionPointTagMatch (ExactMatch, or PartialMatch to also accept child tags).

Screenshot pendingImages/CrimsonUI/howto-extension-point.png
BP_HUDLayout Designer: CrimsonUIExtensionPointWidget in the top-right corner, Extension Point Tag = HUD.Slot.Toasts, Extension Point Tag Match = ExactMatch.

For data-driven extensions (a feature registers a data object instead of a widget class), fill DataClasses with the accepted classes and bind GetWidgetClassForData / ConfigureWidgetForData to map each data object to a widget and initialize it.

2. Register a widget into the slot

Anyone who knows the tag can fill the slot through UCrimsonUIExtensionSubsystem (CrimsonCommon, a world subsystem) - typically a GameFeature action on the full stack, or directly:

Screenshot pendingImages/CrimsonUI/howto-extension-register-bp.png
Get CrimsonUIExtensionSubsystem (world subsystem getter) -> Register Extension (Widget For Context) (Extension Point Tag = HUD.Slot.Toasts, Widget Class = WBP_Toast, Context Object = Get Owning Local Player). Store the returned handle; later call Unregister on it.

Node names (category Crimson|UI Extension): Register Extension (Widget), Register Extension (Widget For Context) (context = the local player, so only that player's HUD shows it), Register Extension (Data) / (Data For Context) for data-driven points. Each returns a handle - call Unregister on it to remove the widget.

On the full stack
CrimsonCore's GFA_AddWidget GameFeature action does this declaratively: its Widgets array pairs a widget class with a HUD.Slot.* tag, registering on HUD spawn and unregistering on feature deactivation. Its Layout array pushes whole layouts to UI.Layer.* layers the same way.
Verify
Registering adds the widget at the extension point immediately; calling Unregister on the handle removes it. Two registrations stack in the entry box.

See also

  • How-To: HUD Layout & Escape Menu - the layout that hosts the points.
  • Concept: Full-Stack Integration & Multiplayer - the GameFeature flow end to end.