0
\$\begingroup\$

I'm trying to implement a state pattern - having skated by with enums forever - and have hit a bit of a wall when it comes to it's implementation in my game. It's a grid based strategy game with an MVC hierarchy.

The general flow is InputManager -> CursorManager -> GridManager. So if the player presses "Up", the InputManager will translate that to the appropriate action and notify the CursorManager. The CursorManager will then update the cursor's world position and then then prompt the GridManager to find what's in the hex in order to update the UI with terrain/unit info.

My new addition is thus having the GridManager change the cursor's state depending on what's in the tile. You pressed up? Let's let the cursor state dictate what happens to the grid. So naturally I created a cursor state object in the CursorManager, but suddenly realized each state needed decent amount of shared information across different the two controllers.

For instance,

public class FreeCursor : CursorState
{
    public override void ActionPressed()
    {
        currState = gridManager.selectTile(cursor.position); 
    }
}

So this means the FreeCursor state would need reference to the GridManager object, reference to the cursor GameObject, and also a reference to the current state itself. All 3 of those are already in the CursorManager, so it's no problem, just throw them all in a constructor: FreeCursor(CursorState context, GridManager gridManager, GameObject goCursor)

But d'oh, when gridManager.tileSelected() completes, it should return the new state. So the GridManager should be saying

public CursorState selectTile(Vector3 position) { 
     //...
     return new FreeCursor(this);
}

...Except now we're missing the GameObject and the current cursor state, which aren't accessible in the GridManager.

So I could go one or two ways - make the GridManager also contain a reference to the context, so it becomes return new SelectedUnitState(this, CursorManager) and changes our flow to be InputManager -> CursorManager <--> GridManager. Or I could say screw it, throw the cursor state and GameObject into the GridManager and call it day.

...But both feel just wrong? The latter through combining two somewhat distinct controllers - the former by making the state be passed it's own containing object like a poor man's reflection or something. Because if I do that, I might as well just use Unity's GameObject.Find(Cursor). Am I wrong to think this? And if so, is the problem with my implementation of the state pattern or the way I've laid out my 'architecture'?

tl;dr: How do you handle a state pattern with data from multiple controllers?

Thanks!

\$\endgroup\$
  • \$\begingroup\$ This is a very academic question - you would do well to post this on StackOverflow, and on perhaps some forums around the internet. \$\endgroup\$ – Natalo77 Mar 31 at 9:07
  • \$\begingroup\$ Ah okay, thanks! \$\endgroup\$ – Robert Lee Mar 31 at 15:54
0
\$\begingroup\$

If anyone comes across this, I think I kind of figured it out.

It's an architectural problem. When the game would change state, say entering into a battle cutscene, there's no reason for the InputManager to interact with the CursorManager. The cursor is deactivated in the background and is irrelevant to the current state. Likewise during the AI turn, the player will not be able to move the cursor.

Thus game state instead should have a HandleInput() section that just handles it on it's own, or for some reason route to another controller.

The flow for the original scenario becomes something like InputManager->BattleManager:handleInput(){moveCusor()}

So yes, in a sense, I'm combining the CursorManager into the GridManager, but it's not pasting two together - it's the way it should probably have been. The only reason I was focused on the direct Input->CursorController was because most games just are Input->PlayerController.

Which is fine...for single state prototypes. My game is just starting to hit the growing pains of putting off making proper game states, that's all.

| improve this answer | |
\$\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.