// ===================== FSMDebugger Window (unchanged API, auto-binding now) ===================== using AlicizaX.Fsm; using UnityEditor; using UnityEngine; internal class FsmDebuggerWindow : EditorWindow { [MenuItem("Window/HighPerfFSM Debugger")] public static void ShowWindow() { var win = GetWindow("FSM Debugger"); win.Show(); } private Vector2 _scroll; private bool _autoRefresh = true; private void OnEnable() { FSMDebugger.SetEnabled(true); EditorApplication.update += RepaintIfNeeded; } private void OnDisable() { EditorApplication.update -= RepaintIfNeeded; } private void RepaintIfNeeded() { if (_autoRefresh) Repaint(); } private void OnGUI() { using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar)) { GUILayout.Label("HighPerfFSM Debugger", EditorStyles.boldLabel); GUILayout.FlexibleSpace(); _autoRefresh = GUILayout.Toggle(_autoRefresh, "Auto Refresh", EditorStyles.toolbarButton); } _scroll = EditorGUILayout.BeginScrollView(_scroll); foreach (var kv in FSMDebugger.Entries) { var entry = kv.Value; EditorGUILayout.BeginVertical("box"); using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label($"ID: {entry.Id}", GUILayout.Width(90)); GUILayout.Label(entry.Name, EditorStyles.boldLabel); GUILayout.FlexibleSpace(); } var stateName = (entry.StateNameGetter != null) ? entry.StateNameGetter(entry.StateIndex) ?? entry.StateIndex.ToString() : entry.StateIndex.ToString(); EditorGUILayout.LabelField("State", stateName); EditorGUILayout.LabelField("TimeInState", entry.TimeInState.ToString("F3")); if (entry.BlackboardGetter != null && entry.Fields != null) { object bbObj = null; try { bbObj = entry.BlackboardGetter(); } catch { } if (bbObj != null) { EditorGUILayout.LabelField("Blackboard"); EditorGUI.indentLevel++; for (int i = 0; i < entry.Fields.Length; i++) { var f = entry.Fields[i]; object val = null; try { val = f.GetValue(bbObj); } catch { } EditorGUILayout.LabelField(f.Name, val != null ? val.ToString() : "null"); } EditorGUI.indentLevel--; } else { EditorGUILayout.HelpBox("Blackboard getter returned null.", MessageType.Info); } } if (entry.Owner != null && entry.Owner.TryGetTarget(out var owner) && owner != null) { EditorGUILayout.ObjectField("Owner", owner, typeof(UnityEngine.Object), true); } EditorGUILayout.EndVertical(); GUILayout.Space(4); } EditorGUILayout.EndScrollView(); if (GUILayout.Button("Clear All (Unregister)")) { var ids = new System.Collections.Generic.List(); foreach (var kv in FSMDebugger.Entries) ids.Add(kv.Key); foreach (var id in ids) FSMDebugger.Unregister(id); } } }