Need help with air stagger mechanic code

I’m attempting to make a mechanic in a 2d game where the player can completely stop their movement in the air for 1 second. I’m now having a problem where the stagger continues after the timer for it is up. Player code below:

extends CharacterBody2D

const SPEED = 300.0
const JUMP_VELOCITY = -400.0

@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D

#timer for stagger
var inStag = false
var Stagused = false
@onready var StagTime: Timer = $StagTimer

func _physics_process(delta: float) → void:

# Add the gravity.
if not is_on_floor():
	
	if inStag == true:
			velocity.y = 0 
			velocity.x = 0
			StagTime.start()
	
	else:
		velocity += get_gravity() * delta


# Handle jump.
if Input.is_action_just_pressed("Jump") and is_on_floor():
	velocity.y = JUMP_VELOCITY
	

#stagger
if Input.is_action_just_pressed("Stagger") and is_on_floor() == false and Stagused == false:
	if StagTime.time_left >= 1:
		if inStag == true:
			inStag = false
			StagTime.stop()
			
		
	else:
		inStag = true
		StagTime.start()
	
	Stagused = true


# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.

#gets input direction that can be either -1, 0, or 1
var direction := Input.get_axis("Move Left", "Move Right")

#flips sprite
if direction > 0:
	animated_sprite.flip_h = false
	
elif direction < 0:
	animated_sprite.flip_h = true
	
#Plays other animations

#If in air
if is_on_floor():		
	#Checks if stagger was used
	Stagused = false
	
		#if Stannding
	if direction == 0:
		animated_sprite.play("Idle")
	
	#if Running
	else:
		animated_sprite.play("Run")
		
#if Falling
else:
	
	if velocity.y > 0:
		animated_sprite.play("Falling")
		
	elif velocity.y == 0:
		animated_sprite.play("Stagger")
		
	else:
		animated_sprite.play("Jump")


if direction:
	velocity.x = direction * SPEED
else:
	velocity.x = move_toward(velocity.x, 0, SPEED)

move_and_slide()

Okay, there are multiple issues.

This part is constantly resetting your timer, so it will never progress:

	if inStag == true:
		velocity.y = 0
		velocity.x = 0
		StagTime.start()

Remove StagTime.start() here.


Then there’s this part:

	if Input.is_action_just_pressed("Stagger") and is_on_floor() == false and Stagused == false:
		if StagTime.time_left >= 1:
			if inStag == true:
				inStag = false
				StagTime.stop()


		else:
			inStag = true
			StagTime.start()

	Stagused = true

First, timers are counting down. To end the air stagger, you would need to check if the time left is below a certain value - or just check StagTimer.is_stopped() instead. (This requires the timer being set to one_shot, which should be done anyway.) Then there would be no need to manually stop the timer as well.

Secondly, the if-statement that checks the timer’s progression should not be inside the if-statement that checks the input. Because otherwise the air stagger could only end on pressing the button again.

So, you should change that part to this:

	if Input.is_action_just_pressed("Stagger") and is_on_floor() == false and Stagused == false:
		inStag = true
		Stagused = true
		StagTime.start()

	if inStag and StagTime.is_stopped():
		inStag = false

Thank you, I ended up solving it the same night I made the post. I pretty much did what you explained. :slightly_smiling_face: