Last active
April 14, 2025 19:17
-
-
Save mrkybe/f9d3cd0b81839b1ffbe892c0c00085f4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using Sirenix.OdinInspector; | |
using Sirenix.OdinInspector.Editor; | |
using UnityEditor; | |
using UnityEngine; | |
public class StateMachineDebugWindow : OdinEditorWindow | |
{ | |
[MenuItem("Tools/State Machine Debug Window")] | |
public static void ShowWindow() | |
{ | |
StateMachineDebugWindow window = GetWindow<StateMachineDebugWindow>(); | |
window.titleContent = new GUIContent("State Machine Debug"); | |
window.Show(); | |
} | |
private const string EditorPrefsSelectedCrewKey = "StateMachineDebugWindow.SelectedCrew"; | |
// --- Added for Dropdown Selection --- | |
[ShowInInspector] | |
[LabelWidth(100)] // Adjust label width for better layout | |
[ValueDropdown(nameof(GetAllCrewInScene), AppendNextDrawer = true, NumberOfItemsBeforeEnablingSearch = 10)] | |
[OnValueChanged(nameof(OnCrewSelectionChanged))] | |
private Crew _selectedCrew; // Instance field to hold the selection | |
private List<Crew> _cachedCrewList = new List<Crew>(); // Cache the list | |
/// <summary> | |
/// Provides the list of Crew instances for the ValueDropdown. | |
/// </summary> | |
private IEnumerable<Crew> GetAllCrewInScene() | |
{ | |
return _cachedCrewList; | |
} | |
private void RefreshCrewList() | |
{ | |
_cachedCrewList = Object.FindObjectsByType<Crew>(FindObjectsInactive.Exclude, FindObjectsSortMode.None).ToList(); | |
if (_selectedCrew != null && !_cachedCrewList.Contains(_selectedCrew)) | |
{ | |
_selectedCrew = null; | |
} | |
Repaint(); | |
} | |
private void OnCrewSelectionChanged() | |
{ | |
if (_selectedCrew != null) | |
{ | |
var id = _selectedCrew.GetInstanceID().ToString(); | |
EditorPrefs.SetString(EditorPrefsSelectedCrewKey, id); | |
} | |
Repaint(); | |
} | |
private void Update() | |
{ | |
if (Application.isPlaying) | |
{ | |
Repaint(); | |
} | |
} | |
protected override void OnEnable() | |
{ | |
base.OnEnable(); | |
RefreshCrewList(); | |
// Load the selected crew from EditorPrefs | |
if (int.TryParse(EditorPrefs.GetString(EditorPrefsSelectedCrewKey), out var id)) | |
{ | |
var obj = (Crew)EditorUtility.InstanceIDToObject(id); | |
if(obj != null) | |
{ | |
_selectedCrew = obj; | |
} | |
else | |
{ | |
EditorPrefs.SetString(EditorPrefsSelectedCrewKey, string.Empty); | |
} | |
} | |
} | |
[InitializeOnLoadMethod] | |
static void OnEditorLoad() | |
{ | |
EditorApplication.playModeStateChanged += HandlePlayModeStateChange; | |
} | |
private static void HandlePlayModeStateChange(PlayModeStateChange state) | |
{ | |
if (state == PlayModeStateChange.EnteredPlayMode || state == PlayModeStateChange.EnteredEditMode) | |
{ | |
if (HasOpenInstances<StateMachineDebugWindow>()) | |
{ | |
var window = GetWindow<StateMachineDebugWindow>(); | |
window.RefreshCrewList(); | |
if (int.TryParse(EditorPrefs.GetString(EditorPrefsSelectedCrewKey), out var id)) | |
{ | |
var obj = (Crew)EditorUtility.InstanceIDToObject(id); | |
window._selectedCrew = obj; | |
} | |
} | |
} | |
} | |
[OnInspectorGUI] | |
protected void OnInspectorGUI() | |
{ | |
if (_selectedCrew == null) | |
{ | |
EditorGUILayout.LabelField("No Crew Selected via dropdown."); | |
return; | |
} | |
if (_selectedCrew.AI == null) | |
{ | |
EditorGUILayout.HelpBox("Selected Crew does not have an AI component.", MessageType.Warning); | |
return; | |
} | |
if (_selectedCrew.AI.States == null || !_selectedCrew.AI.States.Any()) | |
{ | |
EditorGUILayout.HelpBox("Selected Crew's AI has no states.", MessageType.Info); | |
return; | |
} | |
int initialIndentLevel = EditorGUI.indentLevel; | |
EditorGUI.indentLevel++; | |
int executionOrder = 1; | |
var statesToDisplay = _selectedCrew.AI.States; | |
try | |
{ | |
foreach (var state in statesToDisplay) | |
{ | |
if (state == null) continue; | |
EditorGUILayout.LabelField($"{executionOrder}: {state.GetType().Name}", EditorStyles.miniBoldLabel); | |
EditorGUI.indentLevel++; | |
EditorGUILayout.TextArea(state.ToString()); | |
EditorGUI.indentLevel--; | |
executionOrder++; | |
} | |
} | |
catch (System.InvalidOperationException ex) | |
{ | |
EditorGUILayout.HelpBox($"Could not display states in reverse. Is AI.States a Stack? Error: {ex.Message}", MessageType.Warning); | |
} | |
EditorGUI.indentLevel = initialIndentLevel; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment