Quick Start
Goal: one bar of eight ability slots on keys 1-8, editable by the player, replicated, with a stock slot widget bound to it. Roughly fifteen minutes.
CrimsonActionBar enabled, GameplayAbilities enabled, and a player controller class you can edit. Enhanced Input is the project's input system.UCrimsonCoreSlotBindingComponent and UCrimsonCoreActionBarComponent (saved, chord-aware subclasses of this plugin's two components) plus the W_ActionBar / W_ActionBar_Slot widgets. Use those components on your controller in step 2, assign a layout asset, and skip to step 5.1. Enable the plugin
Edit -> Plugins, search Crimson, tick CrimsonActionBar, restart when prompted.
2. Add the store and the bar component to your player controller
Open your player controller Blueprint. Add Component -> Crimson Slot Binding Component, then Add Component -> Crimson Action Bar Component. Compile and save.
COND_OwnerOnly; the bar replicates its layout and manual pages owner-only.3. Create the slot input actions
Each slot needs its own UInputAction (IA_ActionBar_Slot1 ... IA_ActionBar_Slot8, digital bool). Map them to keys 1-8 in the Input Mapping Context your player already receives. Do not reuse the actions your ability input config binds to input tags - two listeners on one key starve each other under Enhanced Input's listener consumption.
Content Browser -> Input -> Input Action x8, then open your IMC and add one mapping per action (One ... Eight).
4. Author the layout asset
Content Browser -> Miscellaneous -> Data Asset -> `CrimsonActionBarLayoutDefinition`, name it DA_ActionBars.
Bars[0].BarTag=ActionBar.Main(add the tag in Project Settings -> Gameplay Tags if it does not exist)Bars[0].Pages[0].LayoutId=ActionBar.Layout.Main.1; add 8 entries toSlots(leave each slot's defaults)Bars[0].SlotInputActions= your eight actions, in orderBars[0].Style: BarWidgetClass = your bar widget ((CrimsonCore - requires all Crimson plugins) shipsW_ActionBar), SlotWidgetClass = your slot widget (W_ActionBar_Slot, whose own class defaults carry its material and colors - the layout asset holds no look). Optional: SlotSize / SlotSpacing (0 / -1 keep the widgets' own design). Leave Arrangement on Flow for a straight bar; Freeform places every slot by hand - see How-To: Shape a BarBars[0].ExtensionPointTag= the HUD extension point the bar lands in (e.g.HUD.Slot.ActionBar.Main) - the tag your HUD code places the bar widget at whenFCrimsonActionBarIntegrationHooks::OnBarWidgetsReadyfires. Step 6 wires that halfProviders-> add Gameplay Abilities (UCrimsonSlotBindingProvider_Ability). ItsProviderIddefaults toActionBar.Provider.Ability
+ to add slots / pages / bars, and a toolbar for Add / Duplicate / Delete. Validation issues show at the top and update as you edit.Hand the asset to the bar component through a game feature action, so each feature or experience can ship its own bars instead of hard-wiring one layout into the controller class.
Open your Game Feature Data (the Game Feature plugin must be Active) -> Actions -> Add -> Add Crimson Action Bars. Add one entry: Actor Class = your player controller class, Layout Definition = DA_ActionBars. Leave the two component-class fields empty (your controller already has the components from step 2). That is the whole action: the asset defines the look, the widgets and the HUD placement; the action just pushes the asset and the components.
UCrimsonGameFeatureAction_AddActionBars applies the layout on the authority when the controller becomes ready, optionally adds the two components to a class that lacks them, and registers one HUD widget per bar at an extension point (step 6). Two features can each add bars: everything is keyed by BarTag and extension point tag, so nothing collides and nothing is baked into a base Blueprint.UGameFrameworkComponentManager::AddGameFrameworkComponentReceiver(this) in your controller's PreInitializeComponents and RemoveGameFrameworkComponentReceiver(this) in EndPlay; for the HUD widgets of step 6, also call UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(this, UGameFrameworkComponentManager::NAME_GameActorReady) once the controller has its player (for example in ReceivedPlayer). Blueprint cannot register a receiver: a Blueprint-only project sets Layout Definition on the Action Bar component's Details (step 2) or calls Set Layout Definition on the server instead.LogCrimsonActionBar at Verbose reports Action bar [ActionBars] linked to slot binding store on [MyPlayerController_0]. Nothing is on screen yet.5. Put an ability on the bar
Grant an ability to the player as you normally do (an ability set, GiveAbility). Then bind it to slot 0 - from a picker later; from code now:
Any Blueprint with the player controller: Find (Crimson Action Bar Component) -> Get Layout Definition -> Providers[0] (cast to CrimsonSlotBindingProvider_Ability) -> Make Binding For Ability (the ability's class default object) -> Assign Binding with Address = (ActionBar.Main, -1, 0).
6. Show it
Bind a widget to the snapshot: How-To: Bind a Slot Widget walks a complete slot widget in both audiences. The short version:
The HUD widget comes from the asset too: each bar's Style.BarWidgetClass and ExtensionPointTag - you already set both in step 4. Once the controller has its local player and its layout, the action fires the C++ hook FCrimsonActionBarIntegrationHooks::OnBarWidgetsReady(RegistrationId, Host, LocalPlayer, Layout) (and OnBarWidgetsRemoved(RegistrationId) on teardown). Bind it once at startup and create each bar's BarWidgetClass for that player at your HUD's slot for ExtensionPointTag, telling the widget its BarTag. One widget class therefore serves every bar. (CrimsonCore - requires all Crimson plugins) binds the hook to CrimsonUI extension points (UCrimsonActionBarWidgetPayload), so there the widget simply appears.
Event Construct -> Find (Crimson Action Bar Component) -> Bind Event to On Slot Changed and On Slot Live State Changed; in the handlers, Get Slot State for (ActionBar.Main, -1, 0) and read State.Display.Icon, State.KeybindText, State.Live.Enabled. On Clicked -> Press Slot then Release Slot.
1 as its keybind, grays out while the ability is on cooldown, and clicking it activates the ability. Play As Client: the same on the client; the server never shows the widget.