Hey guys, first a caveat - I am a beginner when it comes to programming, all of my experience is with Unreal blueprints, and I may use some technical terms incorrectly. I'll try to give concrete examples to avoid confusion.
I am not having a progress blocking issue, I just see a situation where I have a feeling there is a battle-test technique to handle things more efficiently than I know how to. Perhaps some experienced programmers can offer advice?
The situation involves too much code to show - I've tried to condense it with a simple graphic below.
There are two State Machines at play. GameState is watching things happening in the game, recording data about it, etc.
PlayerState is used to determine how input will be handled, and what UI elements will be shown.
An example is that while in the PlayerState:Movement and you press W, the character will move forward (first person style game). While in PlayerState:UI and press W, the current UI menu will move selection up one element.
PlayerState watches GameState because when GameState changes, in most cases PlayerState should also change. E.G., when we go into GameState:PreGame, that is like a countdown where for 5 seconds the player cannot move, therefore they go to PlayerState:InputLocked.
Now you can imagine, if PlayerState is UI and GameState is InGame, ESC might toggle a Pause Menu off. But if it's same PlayerState but GameState is Menu, then ESC should not toggle off the main menu - it would have different functionality.
So, there is this situation where GameState + PlayerState can create additional states that aren't defined. Sort of like there is a multiplication process happening.
The simple, obvious solution is just to do a Switch statement using the GameState as an enumerator on whatever input events need to consider that. But, that has zero modularity and it is going to be difficult to maintain. I find code with lots of conditional checks like that to be very hard to reason about, so I try to avoid it.
So, have you seen a problem like this before? Is there a tried and true method to deal with it? Might you set things up entirely differently? Perhaps I am misusing these state machines?
Any advice is appreciated, thank you.
(about the image: Arrows denote that source causes target to change. E.G. when GameState:Menu is entered, then PlayerState:UI is request to be entered as well.)