When the player is crouched and hurt for the first time, it gets stuck in the fall state

Godot Version

4.2.1

Question

See the video below.

I’ve made the game in a way so that when the player is crouched and if there’s a platform above the player, the crouch state will remain.

When the player is crouched under a platform and gets hurt, it gets stuck in the fall state for a few seconds. Then returns to normal.

After the first attempt, this issue can rarely be replicated.

HURT state code:

extends "State.gd"

@onready var hurt_timer = $HurtTimer #0.3s

var hurt_anim_playing = false

func update(delta):
	Player.velocity = Vector2.ZERO
	Player.apply_gravity(delta)
	if !hurt_anim_playing:
		if Player.is_on_floor():
			return STATES.IDLE
		if Player.is_on_floor() == false:
			return STATES.FALL
		if Player.crouch_input == true:
			return STATES.CROUCH		
	return null
	
		
func enter_state():
	if Player.crouch_input == true:
		Player.animation_player.play("crouch_hurt")
	else:
		Player.animation_player.play("hurt")
	
	hurt_timer.start()
	
	hurt_anim_playing = true

func exit_state():
	hurt_anim_playing = false

func _on_hurt_timer_timeout():
	Player.is_hurt = false
	hurt_anim_playing = false

Any idea on how to rectify this?
Thanks in advance.

	if !hurt_anim_playing:
		if Player.is_on_floor():
			return STATES.IDLE
		if Player.is_on_floor() == false:
			return STATES.FALL
		if Player.crouch_input == true:
			return STATES.CROUCH	

As far as I can tell, this will always return either STATES.IDLE or STATES.FALL, because Player.is_on_floor() must necessarily be either true or false. This means you can never switch from the HURT state back to the CROUCH state with your current code.

That aside, I can’t tell from this code why it would end up in the FALL state rather than IDLE. Does the "crouch_hurt" animation somehow lift the character slightly off the ground or something? You could try showing the value of Player.is_on_floor() on the screen along with the other debug information, to see if it even thinks it’s on the floor.

1 Like

Thank you.
I’ve updated the code of the “HURT state” to the below, based on your comment. And the issue was resolved.

extends "State.gd"

@onready var hurt_timer = $HurtTimer

var hurt_anim_playing = false

func update(delta):
	Player.velocity = Vector2.ZERO
	Player.apply_gravity(delta)
	#print(Player.is_on_floor())
	if !hurt_anim_playing:
		if Player.is_on_floor():
			if Player.crouch_input == true:
				return STATES.CROUCH
			if Player.crouch_input == false:
				return STATES.IDLE
		if Player.is_on_floor() == false:
			return STATES.FALL
		
			
		#if Player.ray_cast_2d_left.is_colliding() or Player.ray_cast_2d_right.is_colliding():
			#return STATES.CROUCH
		
	return null
	
		
func enter_state():
	if Player.crouch_input == true:
		Player.animation_player.play("crouch_hurt")
	else:
		Player.animation_player.play("hurt")
	
	hurt_timer.start()
	
	hurt_anim_playing = true

func exit_state():
	Player.animation_player.stop()
	hurt_anim_playing = false

func _on_hurt_timer_timeout():
	Player.animation_player.stop()
	Player.is_hurt = false
	hurt_anim_playing = false