What is the correct way to using a state machine? I have to admit I have become a little overwhelmed and lost now in the topic after reading many docs and even watching many tutorials around the subject.
There is 2 main areas that I am confused in.
Are the states only meant to handle animations? I read that its good to stick your logic inside there, for me it makes sense. So for example in the case of run and walk, I call the parent node function move and pass in delta, direction and speed so I can get the right speeds for running and walking. But then I noticed other people really seem to just stick their animations logic in there.
in the case of a character controller. I have lets say walk,run,jump,idle states should every state be able to transition to each other? so for example idle → walk → run. But what if I am idle and want to go directly to run? Tho I suppose in the real world you first transition to walk then run. But is that how people do it? Hasn’t this become a huge mess of every state can go to every other state now and transition to them. I am using state charts so maybe this is more something I don’t understand on state charts. I guess what got me thinking about this was more the jump part. Because jump should just transition to whatever the previous state was. Maybe I am over thinking this.
States can handle all kinds of logic. Here is an example of me using states to control movement:
func choose_action() -> void:
match current_state:
States.NEUTRAL:
wander()
States.AGITATED:
flee()
Whether every state can transition to another is a question of what makes sense for your game. For your specific example, is there a reason the character has to walk before they run? If not I wouldn’t implement it. Sprinters go from idle to running.
As for jump - personally I would transition only to a landing that then can transition to any other state.
How you set up the statemachine can be vary diverse.
Personally I prefer to handle the responses in func in my player code, my statemachine just tells my player code what it should be doing.
Any state can move to any other state that makes sense, the important thing is they all lead back to an “idle” or base state eventually (could be via other states first). Otherwise you could end up stuck in a loop that doesn’t reset to 0.
It also depends on how complex your states are how you handle the state logic as well.
But, don’t worry they aren’t only useful for animation controls.
Thanks everyone for your input, I realize that I was really just overthinking it. You both make great points and both say really the same thing so it just makes sense to continue.
State machines are great. They were initially created to handle the fact that a computer (in the 70s to early-90s) could only process one thing at a time and so the computer had to jump back and forth between multiple states and multiple objects with multiple states (like enemies.) Computers are now multithreaded and multi-cored, so they can process a lot more things at once.
Knowing that might help with your confusion. We still use state machines to great effect, but they do get more confusing when you can shoot in any state and jump in any state, etc. Ultimately, do whatever makes your game fun.
It depends on how complex your game is, but often there are states for controlling movement even if you can shoot in every state. I have to use a behavior tree for my project since my ai is more complex then makes reasonable sense to use a statemachine for, however, I still have a small state control for cycling attack and movement which my behavior tree modifies, and my player/computer is constrained by.
I have been playing with the idea of using the AnimationTree AnimationNodeStateMachine as my state machine, as it feels like I’m duplicating a lot of code to then call it to do the animation.
Yeah, i am not super familiar with AnimationTree I have generally used just AnimationPlayer in conjunction with my StateMachine to get the animations when and how I want.