Stamina/Nitro System not working

Godot 4.2.2

I need help with Making a Nitro System for my racing game could anyone help?
This is what I have so far:

func dash():
	SPEED = 1000.0
	ACCEL =  10.0
	$Timer.start()


func _on_timer_timeout():
	SPEED = 450.0
	ACCEL = 4.0

Just so you know the SPEED and ACCEL are not constants they are Variables

What is not working about this? Could you describe what you expect to happen and what really happens?

@gertkeno what is happening is when the Timer finishes it does not stop sprinting/nitro.

As if the on_timer_timeout function does not work

Could you show some more code and/or how your signal is connected to this _on_timer_timeout function?

Here’s all my player code:

extends CharacterBody2D

var animationplayer : AnimationPlayer
var SPEED = 450.0
var ACCEL = 4.0

var input: Vector2
func get_input():
	input.x = Input.get_action_strength("right") - Input.get_action_strength("left")
	input.y = Input.get_action_strength("down") - Input.get_action_strength("up")
	return input.normalized()
	
func _process(delta):
	animationplayer = $AnimationPlayer	
	var playerInput = get_input()
	
	velocity = lerp(velocity, playerInput * SPEED, delta * ACCEL)
	
	move_and_slide()

	if Input.is_action_pressed("left"):
		rotation_degrees = -90
		
	elif Input.is_action_pressed("right"):
		rotation_degrees = 90
		
	elif Input.is_action_pressed("down"):
		rotation_degrees = -180
		
	elif Input.is_action_pressed("up"):
		rotation_degrees = 360
	

func _physics_process(delta):
	if Input.is_action_pressed("dash"):
		dash()
	

func dash():
	SPEED = 1000.0
	ACCEL =  10.0
	$Timer.start()


func _on_timer_timeout():
	SPEED = 450.0
	ACCEL = 4.0

I am still not sure how you are connecting the signal to the function. Two things I notice.

First, you should change _process to _physics_process and combine the dash input into that function. move_and_slide() is supposed to be used in _physics_process.

Second the input for dashing has no cooldown or limit so it will restart the timer while it is held.


Off-topic notes:

  1. use Input.get_vector() normalizing input means controllers are at full-force or 0
func _process(delta):
	var playerInput = Input.get_vector("left", "right", "up", "down")
  1. @onready your animation player, it is costly to get nodes like that every frame
@onready var animationplayer : AnimationPlayer = $AnimationPlayer
  1. lerp is frame-dependant and exaccerbated by multiplying by delta, since it’s an acceleration you want, use move_toward
velocity = velocity.move_toward(playerInput * SPEED, delta * ACCEL)

I am connecting the Timer node by

And also how do add a limit or cooldown?

I assume a nitro system you want will be another variable, spending nitro increases speed and accel until nitro is depleted. The timer would help prevent mashing the dash button, but it is optional.

var nitro_charge: float = 1 # seconds of nitro

func _physics_process(delta: float) -> void:

	if Input.is_action_pressed("dash") and nitro_charge > 0.0:
		SPEED = 1000.0
		ACCEL = 10.0
		nitro_charge -= delta
	else:
		SPEED = 450.0
		ACCEL = 4.0

	velocity = velocity.move_toward(playerInput * SPEED, delta * ACCEL)
	
	move_and_slide()

If you just want to press the dash button once to activate it for the entire duration then you are on the right track with a timer, just check if it’s already active before restarting the timer.

if Input.is_action_just_pressed("dash") and timer.is_stopped():
    dash()
    timer.start()

I can’t put the _physics_process_delta twice

Not twice, merge the last _physics_process.

	elif Input.is_action_pressed("up"):
		rotation_degrees = 360
	

#func _physics_process(delta): # removing this line solves the issue
	if Input.is_action_pressed("dash"):
		dash()

It isn’t working :frowning:

It doesn’t stop after 1 second.

Could you post your script after all of these changes? Have you tried adding a print or breakpoint to the timeout function?

extends CharacterBody2D

var animationplayer : AnimationPlayer
var SPEED = 450.0
var ACCEL = 4.0

var input: Vector2
func get_input():
	input.x = Input.get_action_strength("right") - Input.get_action_strength("left")
	input.y = Input.get_action_strength("down") - Input.get_action_strength("up")
	return input.normalized()
	
func _physics_process(delta: float) -> void:
	var nitro_charge: float = 1
	animationplayer = $AnimationPlayer	
	var playerInput = get_input()
	
	velocity = lerp(velocity, playerInput * SPEED, delta * ACCEL)
	
	move_and_slide()

	if Input.is_action_pressed("left"):
		rotation_degrees = -90
	elif Input.is_action_pressed("right"):
		rotation_degrees = 90
		
	elif Input.is_action_pressed("down"):
		rotation_degrees = -180
		
	elif Input.is_action_pressed("up"):
		rotation_degrees = 360
	
	
	if Input.is_action_pressed("dash") and nitro_charge > 0.0:
		SPEED = 1000.0
		ACCEL = 10.0
		nitro_charge -= delta
	else:
		SPEED = 450.0
		ACCEL = 4.0

	velocity = velocity.move_toward(playerInput * SPEED, delta * ACCEL)
	
	move_and_slide()

Every time I add the changes you have sent me it gives me errors or makes the player slower?

You now have two setting velocities and move_and_slide() I could see a lot of issues with this. You also set the nitro_charge variable at the start of _physics_process, this means it will be back to 1.0 every frame, so never actually decreasing.

var nitro_charge: float = 1
func _physics_process(delta: float) -> void:
	animationplayer = $AnimationPlayer	
	var playerInput = get_input()
	
	# remove these two
	#velocity = lerp(velocity, playerInput * SPEED, delta * ACCEL)
	#move_and_slide()

Your player may very well be slower, lerp is a different function from move_toward. It’s more consistent but different. You probably want ACCEL to be much higher now, maybe even twice as much as speed.

I’m only sending you snippets to get on the right path, it’s still up to you to make your scripts. There will be errors and I’m happy to work through them, don’t be discouraged.

I’ll change Nitro charge to before

if Input.is_action_pressed("dash") and nitro_charge > 0.0:
		SPEED = 1000.0
		ACCEL = 10.0
		nitro_charge -= delta
	else:
		SPEED = 450.0
		ACCEL = 4.0