Looking for advice: managing input based on states

Hello,

I am planning out how to manage input. Currently, my player controller handles input and then calls functiosn on the player pawn or widgets directly. This could be replaced with interface calls but for the moment i see no problem with direct communications.

There are a few states in which input bindings have different effect and may speak to different actors.

I think the appropriate design here is something like a state machine. I can use an enumerator to name the states, and when an input is fired, check the enum and a switch will call appropriate actors.

For instance, if we are in the Quick Menu state (a certain widget is active), then WASD wont make the player pawn move, but instead call some other widgets, and so on.

Probably this graph explains easier than words:

I just wanted to see if anybody in the community has done something similar to this? Any problems I might not be aware of? Any simpler way to handle this?

My goal is for it to not be a hard-to-manage jumble of caveats. From what I understand, using a state machine pattern like this should mean that when i need to make changes in the future, each state is self-contained and if i am doing communications through an interface, then add/remove some states or changing logic that happens within a state shouldn’t break the whole system.

Thanks for any advice.

1 Like

Hey @BIGTIMEMASTER! State machines are a great way to control your different control schemes. To use them outside of the animator, you are going to have to use flow control nodes. For example, you can attach all of your states to booleans that while true use the “WhileLoop” and when false, return to the default state. Here is a good example video on the concept of setting something like that up.

3 Likes

thanks!

1 Like

So, that video gave me what I needed to solve my problems. I just want to make a quick summary for anybody in future with similar issues:

In the video he shows three ways to handle states:

  1. you just have a haywire of blueprints with lots of branches. This is probably what your code looks like when you are just figuring things out. This is also what blueprint code usually looks like in most tutorials you’ll find. It technically works, however its a nightmare to maintain or extend.

  2. Use enumerators and switches to control execution flow based on state. This is a little better, but as your code grows in complexity this can be hard to maintain. Too many moving pieces spread all over the place. This is where I was at the time I brought this question up - I was getting things to work, but it felt like there must be a better way.

  3. Lastly, the best solution - it seems complicated at first but after a little practice I realized its super easy to handle and make changes too. This is the method where we make Object classes for each state. This way, you have broken states into separate chunks so you know everything about a state is in this one place. No hunting around.

It’s one of those things when you read about it sounds confusing as hell but seeing it put into practice is easy to understand. So if you are curious just watch the video and spend a few hours practicing. Well worth it - now what would have been overly complicated has been simplified significantly.

Quick example of some testing I was doing:

So the State Object I am toggling on a key press. If it is set to null then my WASD keys operate character control normally. If another state is constructed then the input gets fed into the object. Then I can process what to do with the input however I want.


(i suppose you could have functions for each key mapping. But this works.)

I also fed in HUD widget and other stuff so that I can basically run whatever operations I want. Of course you can send interface calls and event dispatches as well.

And I also tested logic for changing to further states from within a state and that is all straightforward. This has made it possible to have a complex contextual UI menu that reuses input keys and communicates with many actors - all while having very little drain on my brain.

Okay, well this is answered. Thank you!

yeah i can see how that makes sense for managing different actors. But then you have to micromanage who gets input priority?

In my case, there is only one actor, just depending on what layer of UI menus you are in, the WASD and a few other keys should do different things. So using the object states like this means I just have a single place I can go to do everything necessary for “menu A is on” state, rather than having a million switches and branches and flags to keep track of.

I wasnt on these forums back in the glory days, but it seems like such is the case for most the forums I frequent. A golden era from around 2014-2016 and tapering off after there. I wonder why. I guess most people are on discord or similar. I find live chat to be too distracting. Anywho, at least forums are easy to search!

I think i understand what you mean sort of. But in my case, this is 99% for getting around through UI menus.

Think like a radial menu, where each pie element is bound to a hotkey, and you can drill down into deeper menus just reusing those same WASD keys each time. And then one universal cancel all key will return back to regular input mode button.

This use of object classes has made it a lot simpler. Before I had huge graphs with all these complex conditions - very hard to manage and debug. Now its just like tossing things in a bucket.

This UI state? It gets mouse control, W key does this. Doesnt do anything with D key.
That UI state? No need for mouse control, A does this, etc.

I initially went for a diegetic approach with this game but that made it too hard in some cases. And also there was too many keys. So mostly I am trying to keep it as minimal keys as possible, which is a challenge given that it’s a simulation game with unique input needs (in other words, I cant jsut copy standard shooter templates).