how do i make a sprint cooldown for my 3d game?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Dylised

i want a sprint cooldown for my 3d horror game, here is my current fps controller:

extends KinematicBody

var mouse_sensitivity = 1
var joystick_deadzone = 0.2

var run_speed = 20
var walk_speed = run_speed / 2
var crouch_speed = run_speed / 4
var jump_height = 5.5

var current_speed = run_speed

var ground_acceleration = 10
var air_acceleration = 5
var acceleration = air_acceleration

var direction = Vector3()
var velocity = Vector3() # Direction with acceleration added
var movement = Vector3() # Velocity with gravity added

var gravity = 12
var gravity_vec = Vector3()

var snapped = false
var can_jump = true
var crouched = false
var can_crouch = true

Data:

var player_speed = 0
var falling_velocity = 0

func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _input(event):
# Look with the mouse
if event is InputEventMouseMotion:
rotation_degrees.y -= event.relative.x * mouse_sensitivity / 18
$Head.rotation_degrees.x -= event.relative.y * mouse_sensitivity / 18
$Head.rotation_degrees.x = clamp($Head.rotation_degrees.x, -90, 90)

direction = Vector3()

func _physics_process(delta):
# Look with the right analog of the joystick
if Input.get_joy_axis(0, 2) < -joystick_deadzone or Input.get_joy_axis(0, 2) > joystick_deadzone:
rotation_degrees.y -= Input.get_joy_axis(0, 2) * 2
if Input.get_joy_axis(0, 3) < -joystick_deadzone or Input.get_joy_axis(0, 3) > joystick_deadzone:
$Head.rotation_degrees.x = clamp($Head.rotation_degrees.x - Input.get_joy_axis(0, 3) * 2, -90, 90)

# Direction inputs
direction = Vector3()

if Input.is_key_pressed(KEY_W) or Input.is_key_pressed(KEY_Z) or Input.is_key_pressed(KEY_UP):
	direction.z += -1
if Input.is_key_pressed(KEY_S) or Input.is_key_pressed(KEY_DOWN):
	direction.z += 1
if Input.is_key_pressed(KEY_A) or Input.is_key_pressed(KEY_Q) or Input.is_key_pressed(KEY_LEFT):
	direction.x += -1
if Input.is_key_pressed(KEY_D) or Input.is_key_pressed(KEY_RIGHT):
	direction.x += 1
	
direction = direction.normalized()

#If we aren't using the keyboard, take the input from the left analog of the joystick
if direction == Vector3():
	direction.z = Input.get_joy_axis(0, 1)
	direction.x = Input.get_joy_axis(0, 0)
	
	# Apply a deadzone to the joystick
	if direction.z < joystick_deadzone and direction.z > -joystick_deadzone:
		direction.z = 0
	if direction.x < joystick_deadzone and direction.x > -joystick_deadzone:
		direction.x = 0

# Rotates the direction from the Y axis to move forward
direction = direction.rotated(Vector3.UP, rotation.y)

# Snaps the character on the ground and changes the gravity vector to climb
# slopes at the same speed until 45 degrees
if is_on_floor():
	if snapped == false:
		falling_velocity = gravity_vec.y
		land_animation()
	acceleration = ground_acceleration
	movement.y = 0
	gravity_vec = -get_floor_normal() * 10
	snapped = true
else:
	acceleration = air_acceleration
	if snapped:
		gravity_vec = Vector3()
		snapped = false
	else:
		gravity_vec += Vector3.DOWN * gravity * delta

if is_on_floor():
	if Input.is_key_pressed(KEY_SHIFT) or Input.get_joy_axis(0, 6) >= 0.6:
		current_speed = run_speed
	else:
		current_speed = walk_speed
	if crouched:
		current_speed = crouch_speed

if Input.is_key_pressed(KEY_SPACE) or Input.is_joy_button_pressed(0, JOY_XBOX_A):
	if is_on_floor() and can_jump:
		snapped = false
		can_jump = false
		gravity_vec = Vector3.UP * jump_height
else:
	can_jump = true

if is_on_ceiling():
	gravity_vec.y = 0

if Input.is_key_pressed(KEY_CONTROL) or Input.is_key_pressed(KEY_C) or Input.is_joy_button_pressed(0, JOY_XBOX_B):
	crouch_animation(true)
else:
	crouch_animation(false)

velocity = velocity.linear_interpolate(direction * current_speed, acceleration * delta)

movement.x = velocity.x + gravity_vec.x
movement.z = velocity.z + gravity_vec.z
movement.y = gravity_vec.y

movement = move_and_slide(movement, Vector3.UP)

player_speed = movement.length()

func land_animation():
var movement_y = clamp(falling_velocity, -20, 0) / 40

$LandTween.interpolate_property($Head/Camera, "translation:y", 0, movement_y, 0.1, Tween.TRANS_SINE, Tween.EASE_OUT)
$LandTween.interpolate_property($Head/Camera, "translation:y", movement_y, 0, 0.25, Tween.TRANS_SINE, Tween.EASE_IN_OUT, 0.1)
$LandTween.start()

func crouch_animation(button_pressed):
if button_pressed:
if not crouched:
$CrouchTween.interpolate_property($MeshInstance, “mesh:mid_height”, $MeshInstance.mesh.mid_height, 0.25, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.interpolate_property($CollisionShape, “shape:height”, $CollisionShape.shape.height, 0.25, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.interpolate_property($Head, “translation:y”, $Head.translation.y, 1.35, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.start()
crouched = true
else:
if crouched:
$CrouchTween.interpolate_property($MeshInstance, “mesh:mid_height”, $MeshInstance.mesh.mid_height, 0.75, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.interpolate_property($CollisionShape, “shape:height”, $CollisionShape.shape.height, 0.75, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.interpolate_property($Head, “translation:y”, $Head.translation.y, 1.6, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.start()
crouched = false

:bust_in_silhouette: Reply From: Skipperro

I do cooldowns in my game this way:

  1. Create variable for cooldown like var sprintCooldown = 0.0
  2. After you finish sprint, add some value to this variable, like for example sprintCooldown = sprintCooldown + 5.0 if cooldown should take 5 seconds.
  3. If player wants to sprint again, check if sprintCooldown is greather than 0.0. If yes, don’t allow to sprint.
  4. On every frame (_process() function) substract delta from sprintCooldown, but make sure it never goes below 0.0.
  5. If sprintCooldown is 0.0then your check from point 3 will allow player to sprint again.

If you do this this way you can also directly use this variable for displaying cooldown time that’s left for the user on GUI, if you want to do that.
You can also mess around with it, for example extend it if player takes damage or instantly drop it to 0 if he get some powerup - you are free to play with it.

could you write an example piece of code so i understand more?

Dylised | 2022-11-10 04:27

Sure, I’ll write you a simple project later today or tomorrow, depending on how busy I’ll be.

Skipperro | 2022-11-10 07:32

Here you go - whole, simple 2D project ready to download, test and learn from:
https://github.com/Skipperro/Godot-Cooldown-Example

Skipperro | 2022-11-10 22:02

can you make it work with my code by any chance?

extends KinematicBody

var mouse_sensitivity = 1
var joystick_deadzone = 0.2

var speed
var sprint_speed = 7
var default_speed = sprint_speed / 2
var crouch_speed = sprint_speed / 3

var sprinting = false

var current_speed = sprint_speed

var ground_acceleration = 10
var air_acceleration = 5
var acceleration = air_acceleration

var direction = Vector3()
var velocity = Vector3()
var movement = Vector3()

var gravity = 14
var gravity_vec = Vector3()

var snapped = false
var crouched = false
var can_crouch = true

var state = IDLE
var player_speed = 0
var falling_velocity = 0

onready var vignetee = $Head/Camera/SneakyMode
onready var _flashlight = $Head/Camera/Flashlight
onready var anim_play = $Head/Camera/AnimationPlayer

enum {
IDLE,
RUN,
WALK,
CROUCH,
}

func _ready():

Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _input(event):

if event is InputEventMouseMotion:
	rotation_degrees.y -= event.relative.x * mouse_sensitivity / 18
	$Head.rotation_degrees.x -= event.relative.y * mouse_sensitivity / 18
	$Head.rotation_degrees.x = clamp($Head.rotation_degrees.x, -90, 90)
	
direction = Vector3()

func _physics_process(delta):

if Input.get_joy_axis(0, 2) < -joystick_deadzone or Input.get_joy_axis(0, 2) > joystick_deadzone:
	rotation_degrees.y -= Input.get_joy_axis(0, 2) * 2
if Input.get_joy_axis(0, 3) < -joystick_deadzone or Input.get_joy_axis(0, 3) > joystick_deadzone:
	$Head.rotation_degrees.x = clamp($Head.rotation_degrees.x - Input.get_joy_axis(0, 3) * 2, -90, 90)

direction = Vector3()

if Input.is_key_pressed(KEY_W):
	direction.z = -1
if Input.is_key_pressed(KEY_S):
	direction.z = 1
if Input.is_key_pressed(KEY_A):
	direction.x = -1
if Input.is_key_pressed(KEY_D):
	direction.x = 1
	

direction = direction.normalized()


if direction == Vector3():
	direction.z = Input.get_joy_axis(0, 1)
	direction.x = Input.get_joy_axis(0, 0)
	
	
	if direction.z < joystick_deadzone and direction.z > -joystick_deadzone:
		direction.z = 0
	if direction.x < joystick_deadzone and direction.x > -joystick_deadzone:
		direction.x = 0


direction = direction.rotated(Vector3.UP, rotation.y)

if is_on_floor():
	if snapped == false:
		falling_velocity = gravity_vec.y
	acceleration = ground_acceleration
	movement.y = 0
	gravity_vec = -get_floor_normal() * 10
	snapped = true
else:
	acceleration = air_acceleration
	if snapped:
		gravity_vec = Vector3()
		snapped = false
	else:
		gravity_vec += Vector3.DOWN * gravity * delta



if is_on_floor():
	if Input.is_key_pressed(KEY_SHIFT) or Input.get_joy_axis(0, 6) >= 0.6 and direction != Vector3():
		current_speed = sprint_speed
	else:
		current_speed = default_speed
		$Run.play()
	if crouched:
		current_speed = crouch_speed
		$Head/Camera/Flashlight/AnimationPlayer.stop()
		$Run.stop()

if Input.is_key_pressed(KEY_CONTROL) and direction != Vector3():
	$Crouch.play()
	$Walk.stop()
	



if is_on_ceiling():
	gravity_vec.y = 0

if Input.is_key_pressed(KEY_CONTROL) or Input.is_joy_button_pressed(0, JOY_XBOX_B):
	crouch_animation(true)
	vignetee.visible = true
else:
	crouch_animation(false)
	vignetee.visible = false
	
	

velocity = velocity.linear_interpolate(direction * current_speed, acceleration * delta)

movement.x = velocity.x + gravity_vec.x
movement.z = velocity.z + gravity_vec.z
movement.y = gravity_vec.y

movement = move_and_slide(movement, Vector3.UP)

player_speed = movement.length()

movement = move_and_slide(movement, Vector3.UP)

if movement.x == 0 and movement.z == 0.0:
	anim_play.play("idle")
	$Walk.stop()
	$Run.stop()
	$Crouch.stop()

if direction != Vector3() and !Input.is_key_pressed(KEY_SHIFT):
	anim_play.play("Walk")
else:
	anim_play.play("idle")
	$Walk.play()
	
	
if Input.is_key_pressed(KEY_SHIFT) and direction != Vector3():
	$Head/Camera/Flashlight/AnimationPlayer.play("wobble")

func crouch_animation(button_pressed):
if button_pressed:
if not crouched:
$CrouchTween.interpolate_property($MeshInstance, “mesh:mid_height”, $MeshInstance.mesh.mid_height, 0.20, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.interpolate_property($CollisionShape, “shape:height”, $CollisionShape.shape.height, 0.20, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.interpolate_property($Head, “translation:y”, $Head.translation.y, 1.30, 0.1, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.start()
crouched = true
else:
if crouched:
$CrouchTween.interpolate_property($MeshInstance, “mesh:mid_height”, $MeshInstance.mesh.mid_height, 0.75, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.interpolate_property($CollisionShape, “shape:height”, $CollisionShape.shape.height, 0.75, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.interpolate_property($Head, “translation:y”, $Head.translation.y, 1.6, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.start()
crouched = false

Dylised | 2022-11-20 06:15