Task.spawn function and multiple streams of fire with an automatic weapon

hi scripting forum,
im having trouble creating an efficient system for automatic fire of a gun. with my current script, the gun does fire automatically and properly uses the rate of fire function, but you can create multiple “streams” of shooting, presumably due to task.spawn(). how do i go about solving this? thanks in advance

past a few “if” checks in my mouse.button1down function i have this:


-- < prevent multiple shooting loops
if shooting then return end 
shooting = true -- < set shooting to true immediately to prevent duplicate spawns

-- < prevent shooting while reloading
local reload_animation = animation_track_table[equipped_tool_settings.tool_animations.ranged_reload.Name]
if reload_animation and reload_animation.IsPlaying then
	shooting = false -- < reset shooting if reloading
	return
end

-- < stop equip animation if it's still playing
local tool_equip_animation = equipped_tool_settings.tool_animations.equip
if animation_track_table[tool_equip_animation.Name] and animation_track_table[tool_equip_animation.Name].IsPlaying then
	stop_animation(tool_equip_animation.Name, 0.05)
end

local fire_delay = RPM_to_fire_delay(equipped_tool_settings.ranged_rounds_per_minute)

if equipped_tool_settings.ranged_current_mode == "semi" then
	if can_ranged_shoot(equipped_tool_settings) then
		fire_projectile(equipped_tool_settings)
		equipped_tool_settings.ranged_ammo -= equipped_tool_settings.ranged_ammo_usage
		ranged_update_ammo_text(equipped_tool_settings)

		task.delay(fire_delay, function()
			shooting = false -- < reset shooting after delay
		end)
	else
		shooting = false -- < ensure shooting resets if unable to fire
	end
end

if equipped_tool_settings.ranged_current_mode == "auto" then
	task.spawn(function()
		while shooting and can_ranged_shoot(equipped_tool_settings) and equipped_tool ~= nil do
			fire_projectile(equipped_tool_settings)
			equipped_tool_settings.ranged_ammo -= equipped_tool_settings.ranged_ammo_usage
			ranged_update_ammo_text(equipped_tool_settings)
			
			if not shooting then break end -- < force loop exit when shooting is set to false
			
			task.wait(fire_delay)

		end
		shooting = false -- < reset shooting after loop exits
	end)
end

mouse.button1up is pretty simple and by pretty simple i mean 3 lines

mouse.Button1Up:Connect(function()
	shooting = false
end)

any help would be appreciated as im kind of clueless right now. after this im probably going to post another topic asking for help with BURST fire

Hi, I helped someone with a similar problem a while ago, so maybe this will help.

so… instead of task.spawn maybe just use the runservice with either heartbeat or renderstepped and deltatime to do cooldowns in real time?

Exactly, instead of creating a new thread, the shooting code can be run based on the amount of time that has passed. No need for task.wait.

Also, it’s not necessary to use delta time for this, assuming you want to use it for tracking elapsed time. The ‘time()’ method already keeps track of this.