Godot Version
Godot-4
Question
I am having trouble when I need to go from Walk to Idle state. Currently I am checking zero approx however, the player stops moving and the walk animation continues going for a few seconds before switching to idle. This happens because is_zero_approx has not evaluated to true and eventually does but many frames after stopping so the walk animation keeps playing as seen in the video below.
This is how I am currently transitioning between the two states:
if Global.player.velocity.is_zero_approx():
transition.emit("IdlePlayerState")
# Use some epsilon value for transitioning to walking state ( this has some issues )
if Global.player.velocity.length() > 0.00001 and Global.player.is_on_floor():
transition.emit("WalkingPlayerState")
This is my entire player controller code:
func _physics_process(delta):
# Add the gravity.
if not is_on_floor():
velocity.y -= gravity * delta
# Handle jump.
if Input.is_action_just_pressed("jump"):
print("Jumping")
isJumping = true
velocity.y = JUMP_VELOCITY
if !jump_anim.is_playing():
jump_anim.play("jump_up")
if Input.is_action_pressed("sprint"):
camera.transform.origin = _headbob(t_bob, SPRINT_BOB_FREQ)
speed = SPRINT_SPEED
print("We are now sprinting")
else:
speed = WALK_SPEED
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
var input_dir = Input.get_vector("left", "right", "up", "down")
var direction = (head.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if(is_on_floor()):
if isJumping:
jump_anim.play(("jump_down"))
isJumping = false
if direction:
velocity.x = direction.x * speed
velocity.z = direction.z * speed
else:
velocity.x = lerp(velocity.x, direction.x * speed, ACCELERATION)
velocity.z = lerp(velocity.z, direction.z * speed, ACCELERATION)
else:
velocity.x = move_toward(velocity.x, 0, DECELERATION)
velocity.z = move_toward(velocity.z, 0, DECELERATION)
t_bob += delta * velocity.length() * float(is_on_floor())
camera.transform.origin = _headbob(t_bob, WALK_BOB_FREQ)
var velocity_clamped = clamp(velocity.length(), 0.5, SPRINT_SPEED * 2)
var target_fov = BASE_FOV + FOV_CHANGE * velocity_clamped
camera.fov = lerp(camera.fov, target_fov, delta * 8.0)
if Input.is_action_pressed("shoot"):
print("shooting")
_shoot()
move_and_slide()
Would appreciate any help or guidance on how I can handle something like this. Thanks in advance.