From 5cae227fec260636085c18f160dcb04bbdc8dc60 Mon Sep 17 00:00:00 2001 From: Ding Yuntian <1491671119@qq.com> Date: Wed, 24 Jun 2026 22:34:57 +0800 Subject: [PATCH] =?UTF-8?q?feat(framework):=20=E7=8A=B6=E6=80=81=E6=9C=BA?= =?UTF-8?q?=E4=B8=8E=20AnimatorKit=20=E6=94=AF=E6=8C=81=E8=AF=BB=E6=A1=A3?= =?UTF-8?q?=E5=8D=B3=E6=97=B6=E6=81=A2=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Scripts/Framework/OtherKit/AnimatorKit.cs | 61 +++++++++++++++++++ .../StateMachineKit/StateMachineKit.cs | 18 ++++++ 2 files changed, 79 insertions(+) diff --git a/Assets/Scripts/Framework/OtherKit/AnimatorKit.cs b/Assets/Scripts/Framework/OtherKit/AnimatorKit.cs index 908ec95bc..5a75bf263 100644 --- a/Assets/Scripts/Framework/OtherKit/AnimatorKit.cs +++ b/Assets/Scripts/Framework/OtherKit/AnimatorKit.cs @@ -264,6 +264,67 @@ namespace AibisDream.Framework return null; } } + + /// + /// 从 AnimatorController 构建 shortNameHash → 状态短名 映射,供 ActorAnima 快照 Capture 反查。 + /// Editor 下遍历完整状态机;运行时 fallback 为 animationClips 名称(与状态名一致时有效)。 + /// + public static Dictionary BuildStateHashToNameMap(RuntimeAnimatorController controller) + { + var map = new Dictionary(); + if (controller == null) + { + return map; + } + +#if UNITY_EDITOR + if (controller is AnimatorController animatorController) + { + foreach (var layer in animatorController.layers) + { + if (layer.stateMachine != null) + { + CollectStateNamesFromStateMachine(layer.stateMachine, map); + } + } + + return map; + } +#endif + + foreach (var clip in controller.animationClips) + { + if (clip == null) continue; + var hash = Animator.StringToHash(clip.name); + map.TryAdd(hash, clip.name); + } + + return map; + } + +#if UNITY_EDITOR + private static void CollectStateNamesFromStateMachine( + AnimatorStateMachine stateMachine, + Dictionary map) + { + if (stateMachine == null) return; + + foreach (var childState in stateMachine.states) + { + if (childState.state == null) continue; + var hash = Animator.StringToHash(childState.state.name); + map.TryAdd(hash, childState.state.name); + } + + foreach (var subStateMachine in stateMachine.stateMachines) + { + if (subStateMachine.stateMachine != null) + { + CollectStateNamesFromStateMachine(subStateMachine.stateMachine, map); + } + } + } +#endif } /// diff --git a/Assets/Scripts/Framework/StateMachineKit/StateMachineKit.cs b/Assets/Scripts/Framework/StateMachineKit/StateMachineKit.cs index 850f22338..2329fed8c 100644 --- a/Assets/Scripts/Framework/StateMachineKit/StateMachineKit.cs +++ b/Assets/Scripts/Framework/StateMachineKit/StateMachineKit.cs @@ -42,6 +42,18 @@ namespace AibisDream.Framework _curState = _createState.Invoke(state, args); } + /// + /// 读档恢复:跳过前一状态的 Exit,直接进入目标状态的 EnterImmediate。 + /// + public IEnumerator SwitchStateImmediate(T nextState, string args = "") + { + if (_curState != null && CurState.Equals(nextState)) yield break; + + _curState = _createState.Invoke(nextState, args); + OnStateSwitch?.Invoke(nextState); + yield return _curState.EnterImmediate(); + } + public IEnumerator QuitState() { yield return _curState?.Exit(); @@ -55,6 +67,12 @@ namespace AibisDream.Framework public void SetArgs(string args) {} public IEnumerator Enter(); + /// 读档恢复:跳过过渡动画,直接到达终态。 + public IEnumerator EnterImmediate() + { + yield break; + } + public IEnumerator Exit() { yield break;