How-To: Gate Combo Branches with Conditions
Goal: make a finisher hit harder only when the player actually landed the whole string - not merely because they mashed the button in time.
What a condition is
A UCrimsonComboTransitionCondition is a per-step observer. The controller creates one instance for each conditional-augment slot on each transition when the step is entered, feeds it everything that happens during that step, and then asks it one question when the player fires the transition: should this transition's augments be granted?
The event itself does not travel downstream. Augments do, gated by the condition's answer.
Step N ability broadcasts Augment.Event.OnHit-> ASC OnAugmentEventBroadcast (spec handle + tag + payload)-> ComboController routes it, filtered to the observed step-> Condition::OnAugmentEvent accumulates "3 of 3 hits landed"-> player presses, transition fires-> Condition::EvaluateCondition -> true / false-> transition ConditionalAugments equipped onto step N+1
1. Create the condition
Subclass UCrimsonComboTransitionCondition. It is Blueprintable and EditInlineNew, so a Blueprint subclass is a first-class choice.
Content Browser -> right-click -> Crimson -> Ability System -> Combo -> Transition Condition. Name it TC_LandedEveryHit.
Add an int32 variable HitCount, then override these events:
- On Observation Begin -> Set
HitCountto0. This is your reset hook. - On Augment Event -> Branch on
Event TagMatches TagAugment.Event.OnHit-> Increment IntHitCount. - Evaluate Condition -> return
HitCount >= 3.
2. Attach it to a transition
Open the combo graph, click the Transition node into your finisher, and expand Conditional Augments. Add an entry, set Condition to your new class (it instantiates inline), and add the augments to grant under Augments.
3. Make the step broadcast something to count
A condition can only count what the step ability actually broadcasts. Augment.Event.OnHit is emitted for you whenever an ability applies an effect spec to a target through ApplyEffectSpecToTarget. To signal anything else, broadcast your own tag.
In the step ability, call Broadcast Augment Event with an Event Tags container holding your tag (for example Augment.Event.OnComboMark) and a payload. Fire it from an AnimNotify, a trace hit, or wherever the moment actually happens.
Augment.Event.OnActivate never reaches a condition
Augment.Event.OnActivate during its own activation. At that instant the combo controller has not yet recorded the new step, so the event is attributed to the PREVIOUS step and the spec filter correctly drops it. Your condition will never see it.This is not a bug you can configure around, and it is not going to change - the ordering exists because the ability instance does not exist until activation has run.
Concretely, UCrimsonComboController::EnterNode does this:
EnterNode(...)ASC->TryActivateAbility(Spec->Handle) <-- the ability broadcasts OnActivate HERE...CurrentStepState.StepHandle = Spec->Handle; <-- only now is the step identified...BeginConditionObservation(Node, StepAbility); <-- only now do conditions exist
So at the moment OnActivate fires there is no condition to receive it, and CurrentStepState.StepHandle still points at the step you are leaving. The filter is doing its job; the event is genuinely early.
Working around it
Three approaches, in the order you should reach for them.
1. Use `OnObservationBegin` - this is the intended answer. It fires at exactly the moment OnActivate would have been useful, and it hands you the ability itself, so anything you would have read from the activation is available.
Override On Observation Begin. Its Observed Ability pin is the step ability that just activated - Cast To your ability class and read whatever you need. This is also where you reset counters.
2. Broadcast your own tag one beat later. Any augment event emitted during the step - from an AnimNotify, a timer, a trace, or simply the next frame - arrives normally, because by then the controller has registered the step and built the conditions. If you specifically need "activation happened" as an event, emit your own tag instead of relying on OnActivate.
In the step ability, add an AnimNotify early in the montage (or a Delay of 0) and from it call Broadcast Augment Event with your own tag, for example Augment.Event.OnComboMark. The condition observes that tag instead.
3. Nothing else is affected. Augment.Event.OnHit, Augment.Event.OnEnd, Augment.Event.OnCrit, Augment.Event.OnKill and every tag you define yourself all reach conditions normally, because they fire while the step is the observed one. OnActivate is the single exception.
| Event | Reaches a condition? | Use instead |
|---|---|---|
Augment.Event.OnActivate | No - fires before the step is registered | OnObservationBegin |
Augment.Event.OnHit | Yes | - |
Augment.Event.OnEnd | Yes | - |
Augment.Event.OnCrit / OnKill | Yes | - |
| Your own tags | Yes, if broadcast during the step | - |
OnActivate never appears in the event handler, while OnHit does.Observing attributes instead of events
A condition can also watch attribute changes - useful for "only chain if you are above 50 stamina" or "only if you took no damage during that step".
Override Get Observed Attributes and return an array containing the attributes you care about, then override On Observed Attribute Changed to accumulate.
GetObservedAttributes is queried when the step is entered and cached for that step. Returning a different list later has no effect until the next step entry.See also
- How-To: Author a Combo - the graph these conditions attach to.
- How-To: Create and Equip an Augment - what a passing condition grants.
- Concept: Combo System - where conditions sit in the whole flow.
- Concept: Multiplayer and Prediction - why conditions are server-only.