Quick answer: Triggers auto-reset on consumption — if an unintended transition consumes the trigger first, your intended one starves. Disable AnyState transitions that read the trigger, set Interruption Source to None on conflicting transitions, and watch the Animator in Debug mode.
You set the “Attack” trigger from code. The animator should transition to the Attack state. Instead it transitions briefly into a fallback state and back. You set the trigger again; same result. The animator is consuming the trigger somewhere unintended.
How Triggers Work
A trigger is a one-shot Boolean. Setting it via animator.SetTrigger("Attack") raises it. The animator evaluates all outgoing transitions from the current state at each frame; if a transition’s conditions include “Attack” and they’re all true, that transition fires and the trigger is automatically lowered. Two transitions can read the same trigger, but only one consumes it — whichever fires first.
Cause 1: AnyState Transition Stealing the Trigger
You added an AnyState transition with “Attack” as a condition for a debug or fallback state. From any state, the AnyState transition fires first because its priority order in the transitions list happens to be higher than the named-state transition.
Fix: open the Animator, click the AnyState node, and either remove the “Attack” condition or move it below the intended transition in the transition list. Reorder by drag in the Inspector.
Cause 2: Multiple Transitions Reading the Same Trigger
Two transitions from state Locomotion both read “Attack” — one to a Light Attack, one to a Heavy Attack. The order matters. The animator evaluates transitions top to bottom; the first one whose conditions are met fires and consumes the trigger.
If you intend the choice to depend on another parameter (e.g., a “HeavyMod” bool), add that condition to the heavy transition. Make conditions mutually exclusive so only one transition can ever be valid at a time.
Cause 3: Trigger Set While Transitioning
If you SetTrigger during a transition (mid-blend), the animator may or may not honor it depending on Interruption Source:
- None — in-progress transition cannot be interrupted; trigger sits until the transition finishes.
- Current State — transitions out of the current state can interrupt.
- Next State — transitions out of the destination state can interrupt and consume parameters.
- Current State Then Next State / Next State Then Current State — both can, with precedence.
If Interruption Source is Next State on a transition leaving Locomotion, and the destination state has a transition reading Attack, that destination transition can fire before the original transition completes — consuming your trigger before you ever reach Locomotion.
Set Interruption Source to None for guaranteed sequencing:
// In the transition’s Inspector:
// Interruption Source: None
Cause 4: Exit Time Blocking the Transition
The transition has Has Exit Time enabled. Even with the trigger raised, the animator won’t fire the transition until the current state reaches its exit time. Disable Has Exit Time for immediate trigger-driven transitions:
// Transition Inspector:
// Has Exit Time: unchecked
// Transition Duration: 0.1 (or whatever fits)
Debugging in the Animator Window
While in Play mode, open Animator on the GameObject. The parameters list updates live; you can see the trigger toggle to true and back to false. If it never goes true at all, the SetTrigger call isn’t reaching this Animator (wrong layer, wrong controller, prefab override, etc.). If it goes true and false within one frame, a transition is consuming it — look at which state highlights.
Verifying
Add a behaviour at the entry of the intended Attack state:
public class LogStateEnter : StateMachineBehaviour
{
public override void OnStateEnter(Animator a, AnimatorStateInfo s, int l)
{
Debug.Log("Entered Attack at " + Time.frameCount);
}
}
Set the trigger, watch for the log. Logged once: working. Not logged: trigger consumed elsewhere — trace through AnyState and transition lists.
“A trigger is consumed by the first transition that wants it. Make sure that’s the transition you meant.”
AnyState transitions are convenient and cause more bugs than they solve. Prefer explicit per-state transitions.