Skip to content

fix: dual triggers generating false state transition [MTTB-48] #2999

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion com.unity.netcode.gameobjects/Components/NetworkAnimator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,12 @@ private void CheckForStateChange(int layer)
stateChangeDetected = true;
//Debug.Log($"[Cross-Fade] To-Hash: {nt.fullPathHash} | TI-Duration: ({tt.duration}) | TI-Norm: ({tt.normalizedTime}) | From-Hash: ({m_AnimationHash[layer]}) | SI-FPHash: ({st.fullPathHash}) | SI-Norm: ({st.normalizedTime})");
}
else if (!tt.anyState && tt.fullPathHash != m_TransitionHash[layer])
// If we are not transitioned into the "any state" and the animator transition isn't a full path hash (layer to layer) and our pre-built destination state to transition does not contain the
// current layer (i.e. transitioning into a state from another layer) =or= we do contain the layer and the layer contains state to transition to is contained within our pre-built destination
// state then we can handle this transition as a non-cross fade state transition between layers.
// Otherwise, if we don't enter into this then this is a "trigger transition to some state that is now being transitioned back to the Idle state via trigger" or "Dual Triggers" IDLE<-->State.
else if (!tt.anyState && tt.fullPathHash != m_TransitionHash[layer] && (!m_DestinationStateToTransitioninfo.ContainsKey(layer) ||
(m_DestinationStateToTransitioninfo.ContainsKey(layer) && m_DestinationStateToTransitioninfo[layer].ContainsKey(nt.fullPathHash))))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: I wonder if we can split the condition into simpler checks, which makes it easier to understand.

else if (!tt.anyState && tt.fullPathHash != m_TransitionHash[layer])
{
  bool containsLayer = m_DestinationStateToTransitioninfo.ContainsKey(layer);
  bool containsFullPathHash = containsLayer && m_DestinationStateToTransitioninfo[layer].ContainsKey(nt.fullPathHash);

  if (!containsLayer ||  containsFullPathHash)
    {
       // first time in this transition for this layer
       m_TransitionHash[layer] = tt.fullPathHash;
    }

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... it would really be nice to have access to some of the Animator stuff that is available in the editor at runtime...but it gets boiled down to these condensed states.

Although, I think you made me think more about this and that it probably needs some comments...
👍

Copy link
Collaborator Author

@NoelStephensUnity NoelStephensUnity Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some additional comments about that crazy logic... but basically it is avoiding from sending a animation transition that was a trigger to state or trigger from state back to Idle(state) transition which is already sent when one of the two triggers was already set (and sent via RPC).

{
// first time in this transition for this layer
m_TransitionHash[layer] = tt.fullPathHash;
Expand All @@ -841,6 +846,10 @@ private void CheckForStateChange(int layer)
animState.CrossFade = false;
animState.Transition = true;
animState.NormalizedTime = tt.normalizedTime;
if (m_DestinationStateToTransitioninfo.ContainsKey(layer) && m_DestinationStateToTransitioninfo[layer].ContainsKey(nt.fullPathHash))
{
animState.DestinationStateHash = nt.fullPathHash;
}
stateChangeDetected = true;
//Debug.Log($"[Transition] TI-Duration: ({tt.duration}) | TI-Norm: ({tt.normalizedTime}) | From-Hash: ({m_AnimationHash[layer]}) |SI-FPHash: ({st.fullPathHash}) | SI-Norm: ({st.normalizedTime})");
}
Expand Down
61 changes: 32 additions & 29 deletions testproject/Assets/Tests/Manual/ManualTestsMenu.unity
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ RenderSettings:
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
Expand Down Expand Up @@ -104,7 +103,7 @@ NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
serializedVersion: 3
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
Expand All @@ -117,7 +116,7 @@ NavMeshSettings:
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
buildHeightMesh: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
Expand All @@ -128,6 +127,7 @@ PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 8786710035725353936}
m_Modifications:
- target: {fileID: 2848221156307247792, guid: 3200770c16e3b2b4ebe7f604154faac7,
Expand Down Expand Up @@ -247,6 +247,9 @@ PrefabInstance:
objectReference: {fileID: 11400000, guid: 0c59fa26bc04c0f43b7487b42bca86da,
type: 2}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 3200770c16e3b2b4ebe7f604154faac7, type: 3}
--- !u!224 &742723029 stripped
RectTransform:
Expand Down Expand Up @@ -287,7 +290,6 @@ RectTransform:
m_Children:
- {fileID: 2011195074}
m_Father: {fileID: 8786710034940264808}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
Expand Down Expand Up @@ -351,7 +353,9 @@ Canvas:
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_VertexColorAlwaysGammaSpace: 0
m_AdditionalShaderChannelsFlag: 0
m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 360676703
m_SortingOrder: 0
m_TargetDisplay: 0
Expand Down Expand Up @@ -386,7 +390,6 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1757257345}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
Expand Down Expand Up @@ -438,6 +441,7 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5174272713122024596}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1.5825, y: 1.5825, z: 1.5825}
Expand All @@ -446,7 +450,6 @@ Transform:
- {fileID: 8786710036096747217}
- {fileID: 8786710035132639495}
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &5174272713122024596
GameObject:
Expand Down Expand Up @@ -479,7 +482,6 @@ RectTransform:
- {fileID: 8786710035165842725}
- {fileID: 8786710036090056061}
m_Father: {fileID: 8786710035000454139}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 0}
Expand Down Expand Up @@ -612,7 +614,6 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8786710035000454139}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
Expand Down Expand Up @@ -678,13 +679,13 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8786710034828175749}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 627.83386, y: 406.0025, z: -3.938301}
m_LocalScale: {x: 1.5825, y: 1.5825, z: 1.5825}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &8786710034828175754
MonoBehaviour:
Expand Down Expand Up @@ -790,7 +791,6 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8786710036075228519}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 0.2}
Expand Down Expand Up @@ -828,7 +828,6 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8786710035450761404}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
Expand Down Expand Up @@ -884,6 +883,7 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8786710034940264811}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1.5825, y: 1.5825, z: 1.5825}
Expand All @@ -892,7 +892,6 @@ Transform:
- {fileID: 1757257345}
- {fileID: 8786710035725353936}
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &8786710034940264811
GameObject:
Expand Down Expand Up @@ -924,6 +923,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_SceneMenus:
- {fileID: 11400000, guid: f2b30a19875731846a69d285dd4700ac, type: 2}
- {fileID: 11400000, guid: 2c0ff1138526d4041a875c84f7114513, type: 2}
- {fileID: 11400000, guid: 5971e25d82220f448be7385f5d71ece9, type: 2}
- {fileID: 11400000, guid: 17de05ff09d39df47a6bc85ab38dca2f, type: 2}
Expand Down Expand Up @@ -1062,7 +1062,6 @@ RectTransform:
- {fileID: 8786710036761675970}
- {fileID: 8786710034798366468}
m_Father: {fileID: 8786710035725353936}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
Expand Down Expand Up @@ -1163,13 +1162,13 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8786710035132639489}
serializedVersion: 2
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 4387492341889194239}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &8786710035165842724
GameObject:
Expand Down Expand Up @@ -1204,7 +1203,6 @@ RectTransform:
m_Children:
- {fileID: 8786710036154109432}
m_Father: {fileID: 8786710034798366468}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
Expand Down Expand Up @@ -1331,7 +1329,6 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8786710035450761404}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
Expand All @@ -1354,7 +1351,6 @@ RectTransform:
- {fileID: 8786710035740622621}
- {fileID: 8786710034910084049}
m_Father: {fileID: 8786710036154109432}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 1, y: 0.5}
Expand Down Expand Up @@ -1480,7 +1476,6 @@ RectTransform:
- {fileID: 8786710036691323753}
- {fileID: 8786710036003025139}
m_Father: {fileID: 8786710034940264808}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
Expand Down Expand Up @@ -1527,7 +1522,9 @@ Canvas:
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_VertexColorAlwaysGammaSpace: 0
m_AdditionalShaderChannelsFlag: 0
m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
Expand Down Expand Up @@ -1600,7 +1597,6 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8786710035450761404}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
Expand Down Expand Up @@ -1726,7 +1722,6 @@ RectTransform:
m_Children:
- {fileID: 8786710036368978967}
m_Father: {fileID: 8786710035725353936}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
Expand Down Expand Up @@ -1771,7 +1766,6 @@ RectTransform:
m_Children:
- {fileID: 8786710034868932479}
m_Father: {fileID: 8786710036090056061}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
Expand Down Expand Up @@ -1898,7 +1892,6 @@ RectTransform:
m_Children:
- {fileID: 8786710036075228519}
m_Father: {fileID: 8786710034798366468}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 1}
Expand All @@ -1919,9 +1912,17 @@ Camera:
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_Iso: 200
m_ShutterSpeed: 0.005
m_Aperture: 16
m_FocusDistance: 10
m_FocalLength: 50
m_BladeCount: 5
m_Curvature: {x: 2, y: 11}
m_BarrelClipping: 0.25
m_Anamorphism: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
Expand Down Expand Up @@ -1955,13 +1956,13 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8786710036096747218}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 4387492341889194239}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &8786710036096747218
GameObject:
Expand Down Expand Up @@ -1994,7 +1995,6 @@ RectTransform:
m_Children:
- {fileID: 8786710035450761404}
m_Father: {fileID: 8786710035165842725}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 1, y: 1}
Expand Down Expand Up @@ -2090,7 +2090,6 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8786710035725353936}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1}
m_AnchorMax: {x: 0.5, y: 1}
Expand Down Expand Up @@ -2170,7 +2169,6 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8786710036003025139}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
Expand Down Expand Up @@ -2208,7 +2206,6 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8786710035725353936}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1}
m_AnchorMax: {x: 0.5, y: 1}
Expand Down Expand Up @@ -2278,7 +2275,6 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8786710035000454139}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0.5}
m_AnchorMax: {x: 1, y: 0.5}
Expand Down Expand Up @@ -2333,3 +2329,10 @@ GameObject:
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
m_Roots:
- {fileID: 8786710034828175752}
- {fileID: 4387492341889194239}
- {fileID: 8786710034940264808}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading