1
\$\begingroup\$

I've got a simple state machine for handling game states which works using GameObjects 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 MonoBehaviors when applying a custom inspector?

\$\endgroup\$
  • 1
    \$\begingroup\$ Peek throws an exception if the Stack is empty. \$\endgroup\$ – jzx Mar 28 '16 at 9:19
  • 1
    \$\begingroup\$ @jzx Thank you sooo much! I should have read the documentation about the stack collection. :/ Well, I'd expected it to just return null when there's no item to retrieve. Can you post this as the answer so I can close the question? \$\endgroup\$ – artganify Mar 28 '16 at 9:27
1
\$\begingroup\$

Peek throws an exception if the Stack is empty, so you will need to check wherever appropriate that Count > 0 beforehand, or use try/catch if that matches your intent better.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.