How to implement firerate for a bulet

Godot Version

Godot 4.2.2

Question

Oct 1 - So for a while I've been trying to code in guns for my game. I've finished with the daunting task of my gun actually showing but now my fire_rate that i've implemented no longer works. I want to be able to use this gun script for a variety of weapons I have planned like Shotguns and smgs. The code below is what I've done for the M4A1.


@export var gunname: String
@export var spread_angle: float  # Angle for bullet spread (in degrees)
@export var ultcharge: float
@export var firerate: float   # Time in seconds between shots
@export var base_damage: int
@export var max_ammo: int = 30
@export var current_ammo: int
@export var reload_amount: int = 30
@export var last_shot_time: float = 0.0

@onready var anim = $"MAR14 Animations"
@onready var parent_rotation = get_parent()
var bullet_scene = preload("res://scenes/bullet.tscn")
var is_reloading: bool = false

func _ready() -> void:
	current_ammo = max_ammo
	anim.animation_finished.connect(_on_animation_finished)

func _process(delta: float) -> void:
	
	last_shot_time += delta
	
	if Input.is_action_pressed("ui_1"):
		if anim.animation != "equip":
			anim.play("equip")
			
	elif Input.is_action_just_released("ui_1"):
		await get_tree().create_timer(0.39).timeout
		anim.play("m4a1")
	
	if Input.is_action_pressed("ui_shoot"):
		if last_shot_time >= firerate and current_ammo > 0 and not is_reloading:
			shoot_bullets()
			anim.play("shooting")  # Play shooting animation
			print("Shot fired!")  # Debug shot firing
			last_shot_time = 0.0
		elif current_ammo == 0: 
			anim.stop()  # Stop the shooting animation if out of ammo
			print("Out of ammo.")  # Debug output

	elif Input.is_action_just_released("ui_shoot"):
		if anim.animation == "shooting":
			anim.play("smoke")

	if Input.is_action_just_pressed("ui_reload"):
		if not is_reloading and anim.animation != "reload":
			reload_ammo(reload_amount)

func shoot_bullets() -> void:
	var bullet_count = 1
	for i in range(bullet_count):
		var bullet_instance: Area2D = bullet_scene.instantiate()
		if bullet_instance:
			add_child(bullet_instance)
			var spread: float = randf_range(-spread_angle, spread_angle) # Convert to radians
			var direction: Vector2 = (get_global_mouse_position() - global_position).normalized().rotated(spread)
			var damage: int = base_damage + randi() % 10  # Random damage variation
			
			bullet_instance.init(damage, direction)
			bullet_instance.position = global_position
			bullet_instance.top_level = true

	current_ammo -= 1  # Decrement ammo by 1 per shot

func reload_ammo(amount: int) -> void:
	is_reloading = true
	anim.play("reload")
	if current_ammo < max_ammo:
		current_ammo = min(current_ammo + amount, max_ammo)

func _on_animation_finished() -> void:
	if anim.animation == "reload":
		is_reloading = false  # Reset reloading state```

Hi

I don’t know if this will help you but I made different pistols, you can see how it’s done, short and machine guns, as well as RPGs, cruise missiles and grenades thrown from the hand like F1, but each script is a bit different, here is a link to the script for the AK-47 rifle, it works quite well in my game. But bullets and rockets have separate scripts that are dynamically loaded as scenes. So var blt:Area2D = bullet.instantiate()