Sprint Player state wont transition to another state when another function with the same logic will

Godot Version

4.3

Question

I can change my player state from walking to player (if i replace the CrouchingPlayerState with SlidingPlayerState) in this code

class_name WalkingPlayerState extends PlayerMovementState

@export var SPEED : float = 5.0
@export var ACCELERATION : float = 0.1
@export var DECELERATION : float = 0.25
@export var ANIMATION_TOP_SPEED : float = 2.2

func _enter(previous_state) -> void:
	ANIMATION.play("walking", -1.0, 1.0)

func _exit() -> void:
	ANIMATION.speed_scale = 1.0

func _update(delta):
	PLAYER._update_gravity(delta)
	PLAYER._update_input(SPEED, ACCELERATION, DECELERATION)
	PLAYER._update_velocity(delta)
	
	_set_animation_speed(PLAYER.velocity.length())
	
	if PLAYER.velocity.length() == 0.0:
		transition.emit("IdlePlayerState")
	
	if Input.is_action_just_pressed("sprint") and PLAYER.is_on_floor():
		transition.emit("SprintingPlayerState")
	
	if Input.is_action_just_pressed("crouch") and PLAYER.is_on_floor():
		transition.emit("CrouchingPlayerState")


func _set_animation_speed(speed):
	var alpha = remap(speed, 0.0, SPEED, 0.0, 1.0)
	ANIMATION.speed_scale = lerp(0.0, ANIMATION_TOP_SPEED, alpha)

but my sprint function won’t. Something weird i figured out is that if i put a print statement in the enter function of the sliding state, it wont change states but will print and im assuming it also running the rest of the code in the enter function

class_name SprintingPlayerState extends PlayerMovementState

@export var SPRINT_SPEED : float = 7.0
@export var ACCELERATION : float = 0.1
@export var DECELERATION : float = 0.25
@export var ANIMATION_TOP_SPEED : float = 1.6


# Called when the node enters the scene tree for the first time.
func _enter(previous_state) -> void:
	ANIMATION.play("sprinting", 0.5, 1.0)

func _exit() -> void:
	ANIMATION.speed_scale = 1.0

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _update(delta):
	PLAYER._update_gravity(delta)
	PLAYER._update_input(SPRINT_SPEED, ACCELERATION, DECELERATION)
	PLAYER._update_velocity(delta)
	
	_set_animation_speed(PLAYER.velocity.length())
	
	if Input.is_action_pressed("crouch") and PLAYER.velocity.length() > 6:
		transition.emit("SlidingPlayerState")
	
	if PLAYER.velocity.length() == 0:
		transition.emit("IdlePlayerState")
	
	if Input.is_action_just_released("sprint"):
		transition.emit("WalkingPlayerState")


func _set_animation_speed(speed):
	var alpha = remap(speed, 0.0, SPRINT_SPEED, 0.0, 1.0)
	ANIMATION.speed_scale = lerp(0.0, ANIMATION_TOP_SPEED, alpha)


Accidentally had both be my walking player state my bad

Ok so any other input doesn’t work as well.

func _update(delta):
	PLAYER._update_gravity(delta)
	PLAYER._update_input(SPEED, ACCELERATION, DECELERATION)
	PLAYER._update_velocity()
	
	_set_animation_speed(PLAYER.velocity.length())
	
	if Input.is_action_just_pressed("crouch") and PLAYER.is_on_floor():
		transition.emit("SlidingPlayerState")
	
	if Input.is_action_just_pressed("jump") and PLAYER.is_on_floor():
		transition.emit("JumpingPlayerState")
	
	if PLAYER.velocity.length() == 0:
		transition.emit("IdlePlayerState")
	
	if Input.is_action_just_released("sprint"):
		transition.emit("WalkingPlayerState")

having this doesn’t transfer to Jumping or Sliding. I’m assuming the main problem has to do with the release statement

nope deleting it doesn’t do anything. I don’t understand what the practical difference is

ok something weird is going on because if i use my toggle crouch (ctrl) it slides, but if i use my hold down crouch (c) it won’t? maybe it has something to do with input checking. the walking and idle have always worked so

this is the code for transmitting from my sprint state

	if PLAYER.velocity.length() == 0.0:
		transition.emit("IdlePlayerState")
	
	if Input.is_action_just_pressed("sprint") and PLAYER.is_on_floor():
		transition.emit("SprintingPlayerState")
	
	if Input.is_action_just_pressed("crouch_hold") or Input.is_action_just_pressed("crouch_toggle") and PLAYER.is_on_floor():
		transition.emit("CrouchingPlayerState")
	
	if Input.is_action_just_pressed("jump") and PLAYER.is_on_floor():
		transition.emit("JumpingPlayerState")

and this is the code from my crouching state that shows the toggle function. If i get input c in my enter function, i make toggle false.

	if toggled == true:
		if Input.is_action_just_pressed("crouch_toggle"):
			_uncrouch()
	else:
		if Input.is_action_just_released("crouch_hold"):
			_uncrouch()

I’ll try to experiment more but tbh I’m hesitant to spending anymore time, as if I can’t find the issue I’ll continue to waste time to no avail.

Do you have a way of checking the current player state when running the game so you know if the state you think you are in is indeed the correct state?

yeah i have a window that can be turned on that displays the state

	Global.debug._add_property("Current State", CURRENT_STATE.name, 1)