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\$
2
  • 1
    \$\begingroup\$ Peek throws an exception if the Stack is empty. \$\endgroup\$
    – jzx
    Commented Mar 28, 2016 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
    Commented Mar 28, 2016 at 9:27

1 Answer 1

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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .