Character doesnt change state to idle (2D)

Godot Version

4.2.1

Question

Hi, for the last few weeks I’m trying to make a prototype for my own game, following some tutorials, and trying stuff on my own.
While working on some basic movement I noticed an issue with my State Machine, in short when I go from jump to ground the state machine changes to idle, but when I start walking and stop, my state machine is still in walking state.
I am using lerp to slow down my character when inputs are released to give the character a small slide in their movement, and I’m guessing this is why State doesn’t read velocity.x as 0.
So my question is, is there a way to game detect that character stopped moving ? Or make character slide and then reach velocity.x 0 in a better way ?
Code below.

match state:
	State.AIR:
		if is_on_floor():
			state = State.FLOOR
		if velocity.x == 0 and is_on_floor():
			state = State.IDLE
		velocity.y += gravity
		basic_movement()
		air_dash()
		double_jump()
		move_and_slide()
	State.FLOOR:
		if not is_on_floor():
			state = State.AIR
		if velocity.x == 0 and is_on_floor():
			state = State.IDLE
		double_jump_cooldown = true
		ground_dodge()
		basic_movement()
		basic_jump()
		move_and_slide()
	State.IDLE:
		if not is_on_floor():
			state = State.AIR
		if is_on_floor() and velocity.x != 0:
			state = State.FLOOR
		$AnimationPlayer.play("idle")
		velocity.x = lerp(velocity.x,0.0,0.1)
		basic_jump()
		basic_movement()
		move_and_slide()

func basic_movement():
if Input.is_action_pressed(“ui_right”):
$AnimationPlayer.play(“walking”)
velocity.x = lerp(velocity.x,speed,0.1)
direction = 1
if Input.is_action_pressed(“ui_left”):
$AnimationPlayer.play(“walking”)
velocity.x = lerp(velocity.x,-speed,0.1)
direction = -1
if not Input.is_action_pressed(“ui_right”) and not Input.is_action_pressed(“ui_left”):
#$AnimationPlayer.play(“idle”)
velocity.x = lerp(velocity.x,0.0,0.1)
direction = direction

this is my first post here so i hope i pasted everything in readable way

i dont think this will really work but
make a var for moving
and if you press left or right you make it true and if you stop pressing you make it false
and when you set the status to idle you check if moving == false
i hope i helped :slight_smile:

1 Like

and delete the velocity.x == 0
in the if

var moving = false
State.AIR:
if is_on_floor():
state = State.FLOOR
if moving == false and is_on_floor():
state = State.IDLE
velocity.y += gravity
basic_movement()
air_dash()
double_jump()
move_and_slide()
State.FLOOR:
if not is_on_floor():
state = State.AIR
if velocity.x == 0 and is_on_floor():
state = State.IDLE
double_jump_cooldown = true
ground_dodge()
basic_movement()
basic_jump()
move_and_slide()
State.IDLE:
if not is_on_floor():
state = State.AIR
if is_on_floor() and velocity.x != 0:
state = State.FLOOR
$AnimationPlayer.play(“idle”)
velocity.x = lerp(velocity.x,0.0,0.1)
basic_jump()
basic_movement()
move_and_slide()

State.IDLE:
if not is_on_floor():
state = State.AIR
if is_on_floor() and moving == false
state = State.FLOOR
$AnimationPlayer.play(“idle”)
velocity.x = lerp(velocity.x,0.0,0.1)
basic_jump()
basic_movement()
move_and_slide()
func basic_movement():
if Input.is_action_pressed(“ui_right”):
$AnimationPlayer.play(“walking”)
moving = true
velocity.x = lerp(velocity.x,speed,0.1)
direction = 1
if Input.is_action_pressed(“ui_left”):
moving = true
$AnimationPlayer.play(“walking”)
velocity.x = lerp(velocity.x,-speed,0.1)
direction = -1
if not Input.is_action_pressed(“ui_right”) and not Input.is_action_pressed(“ui_left”):
moving = false
#$AnimationPlayer.play(“idle”)
velocity.x = lerp(velocity.x,0.0,0.1)
direction = direction

Thank you for help, added var, added the change state in functions, and it now works as I wanted it to work. Your awesome thx :3

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