#Need assistance configuring player state machine

25 messages · Page 1 of 1 (latest)

coarse copper
#

gonna be posting a large amount of images to kinda show whats going on

#

node set

#

grounded

#

landing

#

and everything else is unused atm

#

while the state machine works

#

I can't figure out how to utilize the state export variables i.e "Can move" "Can attack" "In air" etc. which is the cause for some of the confusion

#

I also am not sure if all states should connect to a "Base" node, or "GroundedState", it feels like connecting everything back to grounded wouldn't work/ would cause issues. But I really don't know

#

Like I wanted to make a "HitState" but I wanted it to be accessible by all states, i.e like if you get hit in grounded, it moves to hit state, but if you also get hit in air state, it moves to hit state. idk where i should put the logic for that either

#

states are confusing 😭 , any help would be appreciated

chilly cave
#

Out of curiosity, did you follow this tutorial to make your state machine? (cause I also got confused by it)
https://www.youtube.com/watch?v=fuGiJdMrCAk

Break down a complex character into more managable states that run selective code and can transition into each other while controlling animations through AnimationTree and the playback travel function. This is one example of how you can structure a character for a platformer character to scale up to having many animations and different rules for...

▶ Play video
coarse copper
#

if you got confused on how the state machine itself worked, i can show you as mine does work, chris' version is just a bit, messy t-t

#

which in turn made mine messy and now here we are :(

chilly cave
#

Agree. I think the problem is that a state machine is supposed to make you delegate all (or most) actions that a player can do to it's respective State, but for some reason in this tutorial the movement is not handled by the States but the Player itself inside it's _physics_process (this is why he needs the can_move variables in the State class, since he's not handling movement in the States he needs to know whether the State the Player currently is allows him to move)

#

I strongly recommend you to check out this video, I think it explains better how the State Machine works and there's a link to his github so you can check out a simple example
https://www.youtube.com/watch?v=oqFbZoA2lnU

Here's an updated look at how I like to do state machines in Godot 4. I'm going to go over some simpler, starter techniques today, and in the next video I'll go in-depth about techniques you can use when today's examples don't cut it.

Text version: https://shaggydev.com/2023/10/08/godot-4-state-machines

Sample project: https://github.com/thesh...

▶ Play video
coarse copper
chilly cave
# coarse copper Like I wanted to make a "HitState" but I wanted it to be accessible by all state...

Also, since you also asked about this, what you can do is add a signal to your State class (I called this signal "interrupt_state") that takes a State parameter.
Then, in your "_ready" function of your State Machine you connect this signal from all your States to a function that just calls the function "switch_states" with the State parameter that you got from your signal.
Then, inside your Hit State, you emit this signal (with the Hit State as a parameter) whenever you get hit and you automatically enter the Hit State from any other State

coarse copper
coarse copper
chilly cave
chilly cave
# coarse copper Oh thank you so much. I forgot I even asked about it t-t, I'm a little slow so I...

basically something like this

#Inside your State class
signal interrupt_state(next_state: State);


#Inside your State Machine
func init(character: CharacterBody2D):
    for child in get_children():
        if(child is State):
            states.append(child);
            
            child.character = character;
            
            child.connect("interrupt_state", on_state_interrupt_state);
            
    change_state(starting_state);

func on_state_interrupt_state(new_state: State):
    change_state(new_state);


#Inside your Hit State
#Modify this function to fit your needs
func on_hit():
  #If your character health > 0
      emit_signal("interrupt_state", self);

  #Else (health is <= 0)
      emit_signal("interrupt_state", dead_state);
coarse copper