镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

NetworkAnimator: Conditional triggered transitions to Exit node log false errors #3912

Description

@AlbertoFdzM

Description

NetworkAnimator.ParseStateMachineStates() logs Debug.LogError for conditional transitions that target the Exit node of a sub-state machine. These transitions are valid Mecanim configurations — the actual destination is resolved by the parent state machine's StateMachineTransitions — but NetworkAnimator only checks transition.destinationState and transition.destinationStateMachine, both of which are null for Exit transitions.

The error message is:

[<GameObject>][Conditional Transition for <StateName>] Conditional triggered transition has neither a DestinationState nor a DestinationStateMachine! This transition is not likely to synchronize properly.

This is a false positive. The transitions work correctly in Mecanim; the issue is that ParseStateMachineStates does not account for transition.isExit == true when conditions are present.

Additionally, because these transitions are skipped (not added to TransitionStateInfoList), they are also missing from the m_DestinationStateToTransitioninfo lookup table used at runtime for synchronizing late-joining clients. This could mean trigger-based transitions routed through a sub-state machine Exit node may not synchronize properly in multiplayer.

Reproduce Steps

  1. Create an Animator Controller with a sub-state machine (e.g. "Sub SM")
  2. Inside the sub-state machine, add a state (e.g. "State A")
  3. Create a Trigger parameter (e.g. MyTrigger)
  4. Add a conditional transition from "State A" to the Exit node using MyTrigger as condition
  5. In the parent state machine, configure StateMachineTransitions on the sub-state machine node to route to a parent state (e.g. MyTrigger → "State B")
  6. Add a NetworkAnimator component referencing this Animator Controller
  7. Observe Debug.LogError in the Console on every OnValidate (domain reload, component selection, scene save, etc.)

Actual Outcome

Debug.LogError is logged for each trigger condition on each conditional Exit transition:

[<GameObject>][Conditional Transition for State A] Conditional triggered transition has neither a DestinationState nor a DestinationStateMachine! This transition is not likely to synchronize properly. Please file a GitHub issue about this error with details about your Animator's setup.

These transitions are also not added to TransitionStateInfoList, so they are missing from the runtime synchronization lookup table.

Expected Outcome

  • ParseStateMachineStates should check transition.isExit before logging an error. Exit transitions with conditions are valid — the destination is resolved by the parent state machine's StateMachineTransitions.
  • Ideally, the transition info should still be tracked (with the resolved destination from the parent's StateMachineTransitions) so that trigger-based synchronization works correctly through sub-state machine Exit nodes.
  • At minimum, no false LogError should be emitted for valid Animator configurations.

Screenshots

N/A — the issue is in code logic, not visual.

Environment

  • OS: Windows 11 Pro (10.0.26200)
  • Unity Version: 6000.2.6f2
  • Netcode Version: 2.7.0
  • Netcode Commit: N/A
  • Netcode Topology: Client-Server

Additional Context

The relevant code is in NetworkAnimator.cs, inside the #if UNITY_EDITOR block:

// Line ~250: Exit transitions WITHOUT conditions are correctly skipped
if (transition.conditions.Length == 0 && transition.isExit)
{
    // We don't need to worry about exit transitions with no conditions
    continue;
}

// Line ~270-296: But exit transitions WITH conditions fall through to the error
switch (parameter.type)
{
    case AnimatorControllerParameterType.Trigger:
    {
        if (transition.destinationStateMachine != null)
        {
            // Recurses into destination sub-state machine
            ParseStateMachineStates(...);
        }
        else if (transition.destinationState != null)
        {
            // Adds transition info to TransitionStateInfoList
        }
        else
        {
            // This fires for valid Exit transitions with trigger conditions
            Debug.LogError($"[{name}][Conditional Transition for {animatorState.name}] ...");
        }
        break;
    }
}

Suggested fix: Add an isExit check before the error branch, analogous to how destinationStateMachine is handled — resolving the actual destination via the parent state machine's StateMachineTransitions:

else if (transition.isExit)
{
    // Transition targets Exit node — resolve actual destination
    // from parent StateMachine's StateMachineTransitions table
    // and add resolved transition info to TransitionStateInfoList.
}
else
{
    Debug.LogError(...);
}

The unconditional Exit transitions (with HasExitTime and no conditions) are already handled correctly at line ~250 with a continue. The gap is specifically for Exit transitions that have trigger conditions (used for interrupting sub-state machine flows like attack combos).

Activity

  1. NoelStephensUnity commented on Mar 23, 2026

    @NoelStephensUnity
    Member

    Hi @AlbertoFdzM,

    Could you upgrade your version of NGO to v2.11.0 and see if this error continues? I am pretty sure this specific issue was fixed between v2.9 & v2.11.

  2. added
    stat:awaiting-responseAwaiting response from author. This label should be added manually.
    and removed on Mar 23, 2026
  3. github-actions commented on Apr 24, 2026

    @github-actions

    This issue has been automatically marked as stale because it has been awaiting response for over 30 days without any activity.
    Please update the issue with any new information or it may be closed in 30 days.

  4. added
    StaleAdded after 30 days since stat:awaiting response was added (if it's still present)
    on Apr 24, 2026
  5. github-actions commented on May 8, 2026

    @github-actions

    This issue has been automatically closed because it has been stale for 2 weeks without any activity. Feel free to reopen if you have new information to add.

  6. AlbertoFdzM commented on Jun 16, 2026

    @AlbertoFdzM
    Author

    I'm on 2.12.0 and this error is still happenning

  7. reopened this on Jun 23, 2026
  8. removed
    StaleAdded after 30 days since stat:awaiting response was added (if it's still present)
    on Jun 23, 2026
  9. github-actions commented on Jul 8, 2026

    @github-actions

    This issue has been automatically marked as stale because it has been awaiting response for over 2 weeks without any activity.
    Please update the issue with any new information or it may be closed in 2 weeks.

  10. added
    StaleAdded after 30 days since stat:awaiting response was added (if it's still present)
    on Jul 8, 2026
  11. removed
    stat:awaiting-responseAwaiting response from author. This label should be added manually.
    StaleAdded after 30 days since stat:awaiting response was added (if it's still present)
    on Jul 8, 2026
  12. ZakyB commented on Sep 26, 2026

    @ZakyB

    Hi! I was able to reproduce this, and it looks like it also affects late-joining clients, not just editor validation.

    On develop-3.x.x, if a client joins while the Animator is going through:

    State A (Sub SM) -> Exit -> State B

    I get:

    [DestinationState To Transition Info] Layer (0) sub-table does not contain destination state (0)
    

    I tried resolving Exit transitions by walking up through the parent state-machine hierarchy with GetStateMachineTransitions().
    For example:

    else if (transition.isExit)
    {
        AddExitTransitionStateInfo(
            layerIndex,
            animatorState,
            stateMachine,
            transition,
            parameter,
            z,
            parentStateMachines,
            parentStateMachines != null ? parentStateMachines.Count - 1 : -1);
    }

    The resolver follows the hierarchy through nested Exit transitions and also handles transitions targeting another state machine.
    With that change, the validation error is gone, and a late-joining client correctly ends up in State B.
    I also added editor tests for direct and nested Exit transitions.

    Does this look like the right direction? If so, I’d be happy to open a PR.

  13. EmandM commented on Sep 28, 2026

    @EmandM
    Member

    Hi! Thank you for the reproduction here.

    A PR would be super appreciated if you already have a fix and some tests. If you have the time, we'd love to see what you have.

  14. added
    stat:awaiting-responseAwaiting response from author. This label should be added manually.
    and removed on Sep 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

stat:InvestigatingIssue is currently being investigatedstat:awaiting-responseAwaiting response from author. This label should be added manually.stat:awaiting-triageStatus - Awaiting triage from the Netcode team.type:bugBug Report

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions