The blocker system
Abilities and interactions are never enabled or disabled directly. Each one holds a Blockers array
of names, and is active only while that array is empty.
SetActiveWithBlocker(true, "Gripping") → ability suppressed
SetActiveWithBlocker(true, "MenuOpen") → still suppressed, two reasons held
SetActiveWithBlocker(false, "Gripping") → still suppressed, MenuOpen remains
SetActiveWithBlocker(false, "MenuOpen") → ability active again
This is what allows independent systems to suppress the same ability without fighting each other. The grip system can block locomotion while an object is held, the menu can block it while it is open, and neither has to know about the other.
Two helpers build on the same mechanism. setAbilityRestriction on the pawn fans a blocker out to
every ability carrying a given component tag, across both the pawn and every motion controller — use
it to disable a whole class of abilities at once. MC_SetFocusControllerAbility blocks every ability
on a controller except one, giving that ability exclusive use of the hand.
When to use which
| You want to | Use |
|---|---|
| Suppress one ability you have a reference to | SetActiveWithBlocker / SetBlockerAndCheckActive |
| Suppress every ability of a kind on a pawn | setAbilityRestriction with a component tag |
| Give one ability exclusive use of a hand | MC_SetFocusControllerAbility |
| Suppress an interaction on a target object | SetBlocker on the interaction component |
Always remove a blocker with the same reason name you added it with. A mismatched name leaves the ability suppressed permanently, and because nothing errors it presents as "the feature stopped working" much later.