Skip to content

Instantly share code, notes, and snippets.

@mrkybe
Last active April 14, 2025 19:17
Show Gist options
  • Save mrkybe/f9d3cd0b81839b1ffbe892c0c00085f4 to your computer and use it in GitHub Desktop.
Save mrkybe/f9d3cd0b81839b1ffbe892c0c00085f4 to your computer and use it in GitHub Desktop.
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