diff --git a/Editor/Animation/AnimatorCombiner.cs b/Editor/Animation/AnimatorCombiner.cs index 2b83849d..12bf9c59 100644 --- a/Editor/Animation/AnimatorCombiner.cs +++ b/Editor/Animation/AnimatorCombiner.cs @@ -534,7 +534,6 @@ namespace nadena.dev.modular_avatar.animation if (child.stateMachine == null) continue; if (visited.Contains(child.stateMachine)) continue; - visited.Add(child.stateMachine); foreach (var state in VisitStateMachine(child.stateMachine)) { yield return state; diff --git a/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine.meta b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine.meta new file mode 100644 index 00000000..7624cb43 --- /dev/null +++ b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 12b82e17858dd8948ac0df83507e5036 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/SyncedLayerOverrideInSubStateMachine.cs b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/SyncedLayerOverrideInSubStateMachine.cs new file mode 100644 index 00000000..765e1333 --- /dev/null +++ b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/SyncedLayerOverrideInSubStateMachine.cs @@ -0,0 +1,41 @@ +using modular_avatar_tests; +using nadena.dev.ndmf; +using NUnit.Framework; +using UnityEditor.Animations; +using VRC.SDK3.Avatars.Components; + +namespace UnitTests.MergeAnimatorTests.SyncedLayerOverrideInSubStatemachine +{ + public class SyncedLayerOverrideInSubStateMachine : TestBase + { + [Test] + public void SyncedLayerOverride_usesCorrectStateOverride() + { + var controller = LoadAsset("syncedlayer.controller"); + var root = CreateRoot("root"); + var vrc_descriptor = root.GetComponent(); + + var layers = vrc_descriptor.baseAnimationLayers; + for (int i = 0; i < layers.Length; i++) + { + var layer = layers[i]; + if (layer.type == VRCAvatarDescriptor.AnimLayerType.FX) + { + layer.animatorController = controller; + layer.isDefault = false; + } + + layers[i] = layer; + } + + AvatarProcessor.ProcessAvatar(root); + + var fx = FindFxController(root); + + var ac = (AnimatorController) fx.animatorController; + var layer2 = ac.layers[2]; + var motion = layer2.GetOverrideMotion(ac.layers[1].stateMachine.stateMachines[0].stateMachine.states[0].state); + Assert.NotNull(motion); + } + } +} \ No newline at end of file diff --git a/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/SyncedLayerOverrideInSubStateMachine.cs.meta b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/SyncedLayerOverrideInSubStateMachine.cs.meta new file mode 100644 index 00000000..7aa3a66e --- /dev/null +++ b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/SyncedLayerOverrideInSubStateMachine.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 228d6ed47f15495293f8c47053d65212 +timeCreated: 1718414096 \ No newline at end of file diff --git a/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/anim.anim b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/anim.anim new file mode 100644 index 00000000..eba04922 --- /dev/null +++ b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/anim.anim @@ -0,0 +1,122 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!74 &7400000 +AnimationClip: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: anim + serializedVersion: 7 + m_Legacy: 0 + m_Compressed: 0 + m_UseHighQualityCurve: 1 + m_RotationCurves: [] + m_CompressedRotationCurves: [] + m_EulerCurves: [] + m_PositionCurves: [] + m_ScaleCurves: [] + m_FloatCurves: + - serializedVersion: 2 + curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: Infinity + outSlope: Infinity + tangentMode: 103 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + - serializedVersion: 3 + time: 1 + value: 1 + inSlope: Infinity + outSlope: Infinity + tangentMode: 103 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + attribute: m_IsActive + path: Dynamics/PhysBones + classID: 1 + script: {fileID: 0} + flags: 16 + m_PPtrCurves: [] + m_SampleRate: 60 + m_WrapMode: 0 + m_Bounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 0, y: 0, z: 0} + m_ClipBindingConstant: + genericBindings: + - serializedVersion: 2 + path: 1384292332 + attribute: 2086281974 + script: {fileID: 0} + typeID: 1 + customType: 0 + isPPtrCurve: 0 + isIntCurve: 0 + isSerializeReferenceCurve: 0 + pptrCurveMapping: [] + m_AnimationClipSettings: + serializedVersion: 2 + m_AdditiveReferencePoseClip: {fileID: 0} + m_AdditiveReferencePoseTime: 0 + m_StartTime: 0 + m_StopTime: 1 + m_OrientationOffsetY: 0 + m_Level: 0 + m_CycleOffset: 0 + m_HasAdditiveReferencePose: 0 + m_LoopTime: 0 + m_LoopBlend: 0 + m_LoopBlendOrientation: 0 + m_LoopBlendPositionY: 0 + m_LoopBlendPositionXZ: 0 + m_KeepOriginalOrientation: 0 + m_KeepOriginalPositionY: 1 + m_KeepOriginalPositionXZ: 0 + m_HeightFromFeet: 0 + m_Mirror: 0 + m_EditorCurves: + - serializedVersion: 2 + curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: Infinity + outSlope: Infinity + tangentMode: 103 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + - serializedVersion: 3 + time: 1 + value: 1 + inSlope: Infinity + outSlope: Infinity + tangentMode: 103 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + attribute: m_IsActive + path: Dynamics/PhysBones + classID: 1 + script: {fileID: 0} + flags: 16 + m_EulerEditorCurves: [] + m_HasGenericRootTransform: 0 + m_HasMotionFloatCurves: 0 + m_Events: [] diff --git a/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/anim.anim.meta b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/anim.anim.meta new file mode 100644 index 00000000..5453378f --- /dev/null +++ b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/anim.anim.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5398253e7a5aa834db8c2f5bc3171d8c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 7400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/syncedlayer.controller b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/syncedlayer.controller new file mode 100644 index 00000000..03c81732 --- /dev/null +++ b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/syncedlayer.controller @@ -0,0 +1,194 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1107 &-2326409288789462316 +AnimatorStateMachine: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Base Layer + m_ChildStates: + - serializedVersion: 1 + m_State: {fileID: -1408899701018709644} + m_Position: {x: 110, y: 300, z: 0} + m_ChildStateMachines: [] + m_AnyStateTransitions: [] + m_EntryTransitions: [] + m_StateMachineTransitions: {} + m_StateMachineBehaviours: [] + m_AnyStatePosition: {x: 50, y: 20, z: 0} + m_EntryPosition: {x: 50, y: 120, z: 0} + m_ExitPosition: {x: 800, y: 120, z: 0} + m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} + m_DefaultState: {fileID: -1408899701018709644} +--- !u!1107 &-1642169402043590078 +AnimatorStateMachine: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: New Layer 0 + m_ChildStates: [] + m_ChildStateMachines: [] + m_AnyStateTransitions: [] + m_EntryTransitions: [] + m_StateMachineTransitions: {} + m_StateMachineBehaviours: [] + m_AnyStatePosition: {x: 50, y: 20, z: 0} + m_EntryPosition: {x: 50, y: 120, z: 0} + m_ExitPosition: {x: 800, y: 120, z: 0} + m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} + m_DefaultState: {fileID: 0} +--- !u!1102 &-1408899701018709644 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: New Animation + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: [] + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 0 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 7400000, guid: 5398253e7a5aa834db8c2f5bc3171d8c, type: 2} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!91 &9100000 +AnimatorController: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: syncedlayer + serializedVersion: 5 + m_AnimatorParameters: + - m_Name: New Float + m_Type: 1 + m_DefaultFloat: 0 + m_DefaultInt: 0 + m_DefaultBool: 0 + m_Controller: {fileID: 9100000} + m_AnimatorLayers: + - serializedVersion: 5 + m_Name: Base Layer + m_StateMachine: {fileID: -2326409288789462316} + m_Mask: {fileID: 0} + m_Motions: [] + m_Behaviours: [] + m_BlendingMode: 0 + m_SyncedLayerIndex: -1 + m_DefaultWeight: 0 + m_IKPass: 0 + m_SyncedLayerAffectsTiming: 0 + m_Controller: {fileID: 9100000} + - serializedVersion: 5 + m_Name: New Layer + m_StateMachine: {fileID: 7262920810642879716} + m_Mask: {fileID: 0} + m_Motions: [] + m_Behaviours: [] + m_BlendingMode: 0 + m_SyncedLayerIndex: -1 + m_DefaultWeight: 0 + m_IKPass: 0 + m_SyncedLayerAffectsTiming: 0 + m_Controller: {fileID: 9100000} + - serializedVersion: 5 + m_Name: New Layer 0 + m_StateMachine: {fileID: -1642169402043590078} + m_Mask: {fileID: 0} + m_Motions: + - serializedVersion: 2 + m_State: {fileID: 3865398302929714333} + m_Motion: {fileID: 7400000, guid: 5398253e7a5aa834db8c2f5bc3171d8c, type: 2} + m_Behaviours: [] + m_BlendingMode: 0 + m_SyncedLayerIndex: 1 + m_DefaultWeight: 0 + m_IKPass: 0 + m_SyncedLayerAffectsTiming: 0 + m_Controller: {fileID: 9100000} +--- !u!1102 &3865398302929714333 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: New State + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: [] + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 0 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 0} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!1107 &5471235037485634970 +AnimatorStateMachine: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: New StateMachine + m_ChildStates: + - serializedVersion: 1 + m_State: {fileID: 3865398302929714333} + m_Position: {x: 407.90698, y: 75.11633, z: 0} + m_ChildStateMachines: [] + m_AnyStateTransitions: [] + m_EntryTransitions: [] + m_StateMachineTransitions: {} + m_StateMachineBehaviours: [] + m_AnyStatePosition: {x: 50, y: 20, z: 0} + m_EntryPosition: {x: 50, y: 120, z: 0} + m_ExitPosition: {x: 800, y: 120, z: 0} + m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} + m_DefaultState: {fileID: 3865398302929714333} +--- !u!1107 &7262920810642879716 +AnimatorStateMachine: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: New Layer + m_ChildStates: [] + m_ChildStateMachines: + - serializedVersion: 1 + m_StateMachine: {fileID: 5471235037485634970} + m_Position: {x: 37, y: 295, z: 0} + m_AnyStateTransitions: [] + m_EntryTransitions: [] + m_StateMachineTransitions: {} + m_StateMachineBehaviours: [] + m_AnyStatePosition: {x: 50, y: 20, z: 0} + m_EntryPosition: {x: 50, y: 120, z: 0} + m_ExitPosition: {x: 800, y: 120, z: 0} + m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} + m_DefaultState: {fileID: 3865398302929714333} diff --git a/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/syncedlayer.controller.meta b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/syncedlayer.controller.meta new file mode 100644 index 00000000..d2d946c8 --- /dev/null +++ b/UnitTests~/MergeAnimatorTests/SyncedLayerOverrideInSubStatemachine/syncedlayer.controller.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d7ae7ba49a7ba43438e5861ba9aae3cd +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 9100000 + userData: + assetBundleName: + assetBundleVariant: