I've got a simple state machine for handling game states which works using GameObject
s that I enable/disable in order to switch the states. Since some states can be loaded additively (such as the pause menu), I'm using a stack to manage the currently active ones.
public class GameController : MonoBehavior {
private readonly Stack<GameObject> _stateStack = new Stack<GameObject>();
public GameObject ActiveState {
get { return _stateStack.Peek(); }
}
public void SetState(GameObject newState, bool isAdditive = false) {
if(newState = null || newState == ActiveState)
return;
if(!isAdditive) {
while(_stateStack.Count > 0)
PopState();
}
if(!newState.activeInHierarchy)
newState.SetActive(true);
_stateStack.Push(newState);
}
public void PopState() {
var gameState = _statStack.Pop();
if(gameState != null)
gameState.SetActive(false);
}
}
Now I'd like to have a custom editor which allows me to see and set the currently top-most active state.
What I did was this:
[CustomEditor(typeof(GameController))]
public class GameControllerEditor : Editor {
public override void OnInspectorGUI() {
DrawDefaultInspector();
var controller = target as GameController;
if(controller == null)
return;
var newState = EditorGUILayout.ObjectField("ActiveState", controller.ActiveState,
typeof (GameObject), true) as GameObject;
if (newState != controller.ActiveState)
controller.SetState(newState);
}
}
However, the custom editor is never visible and in the console, I see the following exception:
InvalidOperationException: Operation is not valid due to the current state of the object
System.Collections.Generic.Stack'1[UnityEngine.GameObject].Peek()
What does this even mean? What state? Is the stack not initialized? How does Unity instantiate MonoBehavior
s when applying a custom inspector?