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;