I’m creating a 3d doom like game and I want to create a sprinting mechanic that will lower the stamina bar, then once that bar reaches 0 it should stop you from sprinting.

My current code:

Player.gd (this is in process delta btw)


if` Input.is_action_pressed("Shift") and $"../../Control".stamina >= 1:

        SPEED = sprintspeed
    else:
        SPEED = 5

Stamina.gd

func _process(delta):
    if Input.is_action_pressed("Shift"):
            value -= 0.505

func _on_timer_timeout():
    if value <= 99:
        value += 1

Almost everything works, the sprint bar decreases when shift is pressed, and regens when released, it sets the speed to the sprint speed (15) and sets it back to 5 when released. But when it reaches 0 it doesn't stop you from sprinting.

brugh,,,
1) Create a new Node scene, name it Stamina

2) attach script

# stamina.gd
extends Node

class_name Stamina

var is_sprinting = false
var is_regenerating = false

var STAMINA_MAX_VALUE = 20.0

var current_stamina = 20.0
var current_speed = 0

var SPEED_SPRINT = 40.0
var SPEED_WALK = 15.0
var stamina_rengen_timer = Timer.new()
var stamina_rate = 5.0
var STAMINA_RENEG_TIMEOUT = 2

signal stamina_changed(stamina_value)
signal speed_changed(speed_value)
signal stamina_state

func _unhandled_input(event: InputEvent) -> void:
	if event is InputEventKey:
		if event.is_action_pressed("action_sprint"):
			# Sprinting
			if current_stamina > 0:
				stamina_state.emit("Sprinting")
				is_sprinting = true
			stamina_rengen_timer.stop()
			is_regenerating = false
		if event.is_action_released("action_sprint"):
			# Sprinting
			stamina_state.emit("Not sprinting")
			is_sprinting = false
			stamina_rengen_timer.start()
			pass
	pass
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	add_child(stamina_rengen_timer)
	stamina_rengen_timer.wait_time = STAMINA_RENEG_TIMEOUT
	stamina_rengen_timer.timeout.connect(_on_stamina_timeout)
	pass # Replace with function body.

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	if is_sprinting:
		decrease_stamina(delta)
		if current_speed != SPEED_SPRINT:
			current_speed = SPEED_SPRINT
			speed_changed.emit(current_speed)
	else:
		if current_speed != SPEED_WALK:
			current_speed = SPEED_WALK
			speed_changed.emit(current_speed)
		
		increase_stamina(delta)
	pass

func decrease_stamina(_delta):
	if is_sprinting and current_stamina > 0:
		current_stamina -= stamina_rate * _delta
		current_stamina = clampf(current_stamina,0.0, STAMINA_MAX_VALUE)
		if current_stamina <= 0:
			#stamina_rengen_timer.start()
			is_sprinting = false
			stamina_state.emit("No more stamina")

		stamina_changed.emit(current_stamina)
		pass
	pass
	
func increase_stamina(_delta):
	if not is_sprinting and is_regenerating:
		current_stamina += stamina_rate * _delta
		current_stamina = clampf(current_stamina,0.0, STAMINA_MAX_VALUE)
		
		if current_stamina >= STAMINA_MAX_VALUE:
			is_regenerating = false	
			stamina_state.emit("Stamina regenerated")
		stamina_changed.emit(current_stamina)
		pass
	pass
	
func _on_stamina_timeout():
	stamina_state.emit("Regenerating")
	is_regenerating = true
	stamina_rengen_timer.stop()
	pass

3) Add this Stamina node to your player or whatever.

In the ready function of that scene connect these signals:

func _ready() -> void:
	stamina.stamina_changed.connect(_on_stamina_changed)
	stamina.stamina_state.connect(_on_stamina_state_changed)
	stamina.speed_changed.connect(_on_speed_changed)
	
	pass # Replace with function body.

4) create the signal functions to update your data:

func _on_stamina_changed(stamina_val):
	var stmn = "%.2f" % stamina_val
	stamina_val_label.text = "Stamina value: " + str(stmn)
	pass

func _on_stamina_state_changed(state_val):
	stamina_state_label.text = "Stamina state: " + state_val
	
func _on_speed_changed(speed_val):
	speed_label.text = "Current speed: " + str(speed_val)
	pass

In my example i had the data display in the labels.

5) Dont forget to bind the sprint action to a key:

"action_sprint": [KEY_SHIFT],

Either though code or whatever..

brugh..