From 1b07a6b07fda76bd4ba8c8a969354124616c3420 Mon Sep 17 00:00:00 2001 From: Luis Gonzalez Date: Wed, 10 Jun 2026 23:42:44 -0700 Subject: [PATCH] Fix: attack animation collapsed the model into the floor (partial Root clip + WDV) The procedural attack clips key only the Root bone, but the Attack/MeleeSwing states had writeDefaultValues=true -> a partial (Root-only) clip resets every un-keyed bone (Hips/Spine/legs) to Rukhanka defaults (~identity), collapsing the body into the floor (player + enemy). Root carries the mesh-positioning offset (localPos -0.90, identity rot) while Hips/Spine carry the authored orientation. Fix: writeDefaultValues=false on the attack states (leave un-keyed bones in pose, only lean the Root). Patched both controllers + both recipes (PlayerRigTools/EnemyRigTools) so a rebuild can't regress. Rule: partial bone-subset overlay clips => writeDefaultValues=false. Co-Authored-By: Claude Opus 4.8 (1M context) --- Assets/_Project/Animation/AC_EnemyTopDown.controller | 2 +- Assets/_Project/Animation/AC_PlayerTopDown.controller | 2 +- Assets/_Project/Scripts/Editor/EnemyRigTools.cs | 2 +- Assets/_Project/Scripts/Editor/PlayerRigTools.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Assets/_Project/Animation/AC_EnemyTopDown.controller b/Assets/_Project/Animation/AC_EnemyTopDown.controller index f0172f630..0c0c36d84 100644 --- a/Assets/_Project/Animation/AC_EnemyTopDown.controller +++ b/Assets/_Project/Animation/AC_EnemyTopDown.controller @@ -42,7 +42,7 @@ AnimatorState: m_StateMachineBehaviours: [] m_Position: {x: 50, y: 50, z: 0} m_IKOnFeet: 0 - m_WriteDefaultValues: 1 + m_WriteDefaultValues: 0 m_Mirror: 0 m_SpeedParameterActive: 0 m_MirrorParameterActive: 0 diff --git a/Assets/_Project/Animation/AC_PlayerTopDown.controller b/Assets/_Project/Animation/AC_PlayerTopDown.controller index c8254075b..b61afe024 100644 --- a/Assets/_Project/Animation/AC_PlayerTopDown.controller +++ b/Assets/_Project/Animation/AC_PlayerTopDown.controller @@ -283,7 +283,7 @@ AnimatorState: m_StateMachineBehaviours: [] m_Position: {x: 50, y: 50, z: 0} m_IKOnFeet: 0 - m_WriteDefaultValues: 1 + m_WriteDefaultValues: 0 m_Mirror: 0 m_SpeedParameterActive: 0 m_MirrorParameterActive: 0 diff --git a/Assets/_Project/Scripts/Editor/EnemyRigTools.cs b/Assets/_Project/Scripts/Editor/EnemyRigTools.cs index 7818d71ec..15b28edce 100644 --- a/Assets/_Project/Scripts/Editor/EnemyRigTools.cs +++ b/Assets/_Project/Scripts/Editor/EnemyRigTools.cs @@ -146,7 +146,7 @@ namespace ProjectM.EditorTools var attackClipAsset = AssetDatabase.LoadAssetAtPath(AttackClip); var attack = sm.AddState("Attack"); attack.motion = attackClipAsset; - attack.writeDefaultValues = true; + attack.writeDefaultValues = false; // partial (Root-only) clip: MUST be false, else WDV resets every un-keyed bone (Hips/Spine/legs) to identity and the body collapses into the floor var toAttack = sm.AddAnyStateTransition(attack); toAttack.hasExitTime = false; diff --git a/Assets/_Project/Scripts/Editor/PlayerRigTools.cs b/Assets/_Project/Scripts/Editor/PlayerRigTools.cs index 3118a9e48..cd868aedf 100644 --- a/Assets/_Project/Scripts/Editor/PlayerRigTools.cs +++ b/Assets/_Project/Scripts/Editor/PlayerRigTools.cs @@ -50,7 +50,7 @@ namespace ProjectM.EditorTools if (swing == null) { swing = sm.AddState("MeleeSwing"); - swing.writeDefaultValues = true; + swing.writeDefaultValues = false; // partial (Root-only) clip: MUST be false, else WDV resets every un-keyed bone (Hips/Spine/legs) to identity and the body collapses into the floor var toSwing = sm.AddAnyStateTransition(swing); toSwing.hasExitTime = false;