How-To: Gate an Interaction with Conditions
Goal: make an option depend on something the player must have or be - a key in the bag, a level, a permission - without writing the check into the actor. Requirements are UCrimsonInteractionCondition objects attached to the option; this plugin evaluates them on every scan, turns a failure into a message on the prompt (or hides the option), and the interaction's handler re-checks them on the server before anything runs. The actor's gather code stays what it was.
And / Or / Not, a gameplay tag query); you add your own leaves (an item check, an attribute check) as subclasses of the same base. (CrimsonCore - requires all Crimson plugins) ships item, attribute and team-attitude leaves, and its owned stash ships its permission as one.1. Add a condition to an option
Conditions live on the option's Conditions list (inline, instanced) or in a reusable UCrimsonInteractionConditionSet asset referenced from ConditionSets. Every condition on the list is evaluated in order; the first one that is not met decides what happens to the option.
Select the placed actor and open Details -> Interaction Options -> [0] -> Conditions. Press +, and pick Gameplay Tag Query from the class dropdown - the list shows every UCrimsonInteractionCondition subclass, so your own appear here too. Expand the new entry and set TagQuery to the tags the instigator must carry. Under Interaction|Condition, set Failure Behavior to Show Informational and Failure Title to Locked so a player without the tag still sees the actor and is told why.
The array is Instanced, so each entry is a real object owned by this actor - two doors can carry the same condition class with different tags. To reuse one list across many actors, fill a Crimson Interaction Condition Set asset instead and reference it from Condition Sets (step 4).
2. Choose what a failure looks like
| Property | Effect |
|---|---|
FailureBehavior = ShowInformational (default) | The option stays on the prompt as a message: bInformational is set, the failure title replaces its text, the reason becomes its SubText, the key glyph is hidden, a press does nothing, and the context menu lists it grayed with the reason. |
FailureBehavior = Hide | The option is dropped. The player sees nothing - for secrets, or for options that make no sense to advertise. |
FailureTitle | Prompt text while failing ("Locked"). Empty keeps the option's own text. Override GetFailureTitle for a dynamic one ("No Access (Owner: X)"). |
FailureText | Overrides the reason the leaf produced ("Requires the dungeon key"). |
RequirementText | The checklist line for this condition, shown met or not ("Dungeon Key"). Empty lets the leaf word its own (GetRequirementText); the base falls back to the reason while unmet and the class name while met. |
With more than one condition, every one is evaluated and lands on the option's Requirements checklist (FCrimsonInteractionRequirement: text + met). CrimsonCore's prompt widget lists them all with a met / unmet mark, so the player sees the whole recipe at once, not the first thing they lack.
3. Compose conditions
All Of (And), Any Of (Or) and Not take child conditions and behave as one condition on the list: the composite's own failure behavior, title and text apply; a child's are ignored inside it. The Gameplay Tag Query leaf matches a query against the instigator's ability system tags (or the target's with bQueryTarget).
In the same Conditions array, press + and pick Any Of (Or). Expand it, and add the child conditions to its own Conditions array - two Gameplay Tag Query entries, one per key. All Of (And) and Not work the same way.
Set Failure Title, Failure Text and Requirement Text on the composite, not on the children: a composite reports as one condition and its children's wording is ignored. Leave Requirement Text empty and Any Of (Or) joins its children's lines with "or" (All Of (And) joins with "and").
RequirementText; with either key the option opens.4. Reuse a list with a Condition Set
Create a Crimson Interaction Condition Set (Content Browser -> Miscellaneous -> Data Asset), fill its Conditions once, and reference the asset from any option's ConditionSets (or a container's OpenConditionSets in CrimsonCore). Sets are evaluated after the inline list. The same loaded asset on client and server keeps the evaluation identical on both.
UpdateInteractableOptions) evaluates conditions before the ability filter: a Hide failure drops the option; a ShowInformational failure keeps it as a message that skips the ability check. The context-menu wrapper applies the same result, so the more-options menu agrees with the prompt. The client's list is presentation only: CrimsonCore's handler and duration abilities re-gather the target's options on the server and refuse an interaction whose option no longer passes (see Concept: Requirements & Conditions).See also
- Concept: Requirements & Conditions
- How-To: Make an Actor Interactable
- Concept: Multiplayer & Authority