How-To: Make an Actor Interactable

Goal: make any actor expose interaction options (Pick Up, Open, Talk...) by implementing ICrimsonInteractableTarget - the contract the CrimsonInteraction scanner reads to drive prompts and abilities.

Prerequisites
CrimsonCommon is enabled. To actually scan and trigger options at runtime you also need the CrimsonInteraction plugin - but the contract below lives here, so a pickup actor in any plugin can implement it without depending on CrimsonInteraction.

1. Understand the option

Each interaction is an FCrimsonInteractionOption. You fill in the display Text/SubText, choose how it fires (InputType = Instant or Hold, with InputHoldDuration), and pick the gameplay path: grant an ability to the interactor (InteractionAbilityToGrant), activate an ability on the target's own ASC (TargetAbilitySystem + handle), or run a player-side action ability (InteractionActionAbility).

2. Implement the interface

Add ICrimsonInteractableTarget to your actor and override the gather method. In C++ override GatherInteractionOptions and use the FCrimsonInteractionOptionBuilder (it stamps each option's target scope for you). In Blueprint override the K2 Gather Interaction Options event and append to the output array.

Screenshot pendingImages/CrimsonCommon/howto-interactable-implement.png
Class Settings -> Interfaces -> add Crimson Interactable Target, then override K2 Gather Interaction Options and add one option.
Verify
With CrimsonInteraction scanning, walking up to the actor surfaces your option text and the configured input prompt.

3. (Optional) React and arbitrate

Override the lifecycle callbacks for feedback - OnInteractableHovered / OnInteractableUnhovered (highlight on/off) and NotifyInteractionSuccess (a hold/channel completed). In C++ you can also override CustomizeInteractionEventData to attach context to the gameplay event before the ability fires. To pick a winner when several options are offered, implement ICrimsonInteractionInstigator::ChooseBestInteractionOption on the instigator (default picks the first available).

Where the work happens
CrimsonCommon defines the contract only. Scanning for targets, driving the hold timer, and activating the abilities is CrimsonInteraction. That split is exactly why a pickup in CrimsonInventory can be interactable without either plugin including the other.

See also

  • Concept: Decoupling Patterns - why the contract lives in CrimsonCommon
  • API Reference - FCrimsonInteractionOption, FCrimsonInteractionQuery, interaction interfaces