Switching states in a finite state machine

Godot Version

4.0

Question

I’ve been working on this for far too long and my brain has turned to mush. I’m trying to get my player character to “turn around” (animation only) before switching direction
I have done this by adding a Turn_around_state in my finite state machine but now i it won’t change states (it did before without the direction.x != 0)

# if player direction is not the same as the previous direction they were facing and it's not 0 (standing still currently)
# then switch states to turn state
    if character.latest_direction != direction.x and direction.x != 0:
        playback.travel(Turn_node)
        next_state = Turn_state

Please ask if you have any questions or if you need to see any more code, node setup or animation tree node setup

Any and all help is appreciated :))

It seems to me you want to check to see if latest_direction and direction.x have the same sign, not that they’re identical.

1 Like

They are not identical no. Latest direction is a variable I have used for other stuff but I came in handy here. My thought process is that when both direction.x and latest_direction are updating simultaneously they will only be different from each other the moment the player character stops moving in one direction and starts moving in the opposite (or when he stops moving and stands still, hence the direction.x != 0)

Sometimes it’s best to just print values and see what’s happening, but I can see potential failure modes here depending on how latest_direction and direction.x get set.

At the worst, if latest_direction can vary (say, because of an analog stick) you might actually be constantly retriggering the inside of that if block.

1 Like

I think i have gotten stuck in a loop.

I’ve changed the latest_direction variable to a local variable now (the way it was used before was messing it up) But now i need to figure out how to call it so it triggers the turn around state

as well as possibly a reset for the new latest direction variable when reentering the run state

Here is the solution

class_name Groundstate
extends Player_State
#-------------------------------------------
@export var JUMP_VELOCITY = -450.0
@export var air_state : Player_State
@export var death_state : Player_State
@export var hurt_state : Player_State
@export var fall_state : Player_State
@export var attack_state : Player_State
@export var crouch_state : Player_State
@export var dash_state : Player_State
@export var Turn_state : Player_State
@export var Turn_node : String = "Turn_around"
@export var Attack1_node : String = "Attack1"
@export var Crouch_down_node : String = "Crouch_down"
@export var Dash_node : String = "Dash"

var latest_direction = 1 # Now stored as a class member

#-------------------------------------------
func state_input(event : InputEvent):
	if event.is_action_pressed("Jump") and character.is_on_floor():
		Jump()
	if event.is_action_pressed("Melee1"):
		Attack()
	if event.is_action_pressed("ui_down") and character.is_on_floor():
		Crouch()
	if event.is_action_pressed("Dash") and character.is_on_floor():
		Dash()

#-------------------------------------------
func Crouch():
	playback.travel(Crouch_down_node)
	next_state = crouch_state

#-------------------------------------------
func Attack():
	playback.travel(Attack1_node)
	next_state = attack_state

#-------------------------------------------
func Jump():
	character.velocity.y = JUMP_VELOCITY
	next_state = air_state

#-------------------------------------------
func Dash():
	playback.travel(Dash_node)
	next_state = dash_state

#-------------------------------------------
func state_process(_delta):
	var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	character.SPEED = 300.0

	if direction.x != 0:
		if latest_direction != direction.x:
			# If facing direction changes, transition to turn state
			playback.travel(Turn_node)
			next_state = Turn_state

		latest_direction = direction.x  # Update latest direction

	# Check for hurt and death conditions
	if Game.hurt and Game.playerHP > 0:
		next_state = hurt_state
	elif Game.playerHP <= 0:
		next_state = death_state


This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.