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..