How to fix spam shooting

Hello,

I am making a gun system. I made the big stuff for now but if you spam the click button it is like a laser beam. I know I have to use debounce but how?

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

Video:

Source Code:

-- local gun = script.Parent
local player = game.Players.LocalPlayer

local debounce = false

local UserInputService = game:GetService("UserInputService")

local UIS = game:GetService("UserInputService")


local mouse = player:GetMouse()

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local remote_event = ReplicatedStorage:WaitForChild("ShotEvent")     
local shooting  = false

--STUFF
local Players = game:GetService("Players")
local ContextActionService = game:GetService("ContextActionService")
local RunService = game:GetService("RunService")
local camera = workspace.CurrentCamera
-- STUFF DONE!!!

function offsetMouse(number)
	local offsetVal = Vector3.new(math.random(-number,number),math.random(-number,number),0)
	return mouse.Hit.p + offsetVal
end

function genBulletHole(coordFrame)
	local part = Instance.new("Part",game.Workspace)
	part.Anchored = true
	part.CFrame = coordFrame
	game.Debris:AddItem(part,3)
end

gun.Equipped:Connect(function(mouse, character)

	local Players = game:GetService("Players")
	local ContextActionService = game:GetService("ContextActionService")
	local UserInputService = game:GetService("UserInputService")
	local RunService = game:GetService("RunService")

	local camera = workspace.CurrentCamera
	local cameraOffset = Vector3.new(2, 2, 8)
	local player = Players.LocalPlayer

	local character = player.Character or player.CharacterAdded:Wait()

		local humanoid = character:WaitForChild("Humanoid")
		local rootPart = character:WaitForChild("HumanoidRootPart")
		humanoid.AutoRotate = false

		local cameraAngleX = 0
		local cameraAngleY = 0

		local function playerInput(actionName, inputState, inputObject)
			-- Calculate camera/player rotation on input change
			if inputState == Enum.UserInputState.Change then
				cameraAngleX = cameraAngleX - inputObject.Delta.X
				-- Reduce vertical mouse/touch sensitivity and clamp vertical axis
				cameraAngleY = math.clamp(cameraAngleY-inputObject.Delta.Y*0.4, -75, 75)
				-- Rotate root part CFrame by X delta
				rootPart.CFrame = rootPart.CFrame * CFrame.Angles(0, math.rad(-inputObject.Delta.X), 0)
			end
		end
		ContextActionService:BindAction("PlayerInput", playerInput, false, Enum.UserInputType.MouseMovement, Enum.UserInputType.Touch)

		RunService.RenderStepped:Connect(function()
			if camera.CameraType ~= Enum.CameraType.Scriptable then
				camera.CameraType = Enum.CameraType.Scriptable
			end
			local startCFrame = CFrame.new((rootPart.CFrame.Position)) * CFrame.Angles(0, math.rad(cameraAngleX), 0) * CFrame.Angles(math.rad(cameraAngleY), 0, 0)
			local cameraCFrame = startCFrame:ToWorldSpace(CFrame.new(cameraOffset.X, cameraOffset.Y, cameraOffset.Z))
			local cameraFocus = startCFrame:ToWorldSpace(CFrame.new(cameraOffset.X, cameraOffset.Y, -10000))
			camera.CFrame = CFrame.new(cameraCFrame.Position, cameraFocus.Position)
		end)
	end)

	local function focusControl(actionName, inputState, inputObject)
		-- Lock and hide mouse icon on input began
		if inputState == Enum.UserInputState.Begin then
			UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
			UserInputService.MouseIconEnabled = false
			ContextActionService:UnbindAction("FocusControl", focusControl, false, Enum.UserInputType.MouseButton1, Enum.UserInputType.Touch, Enum.UserInputType.Focus)
		end
	end
	ContextActionService:BindAction("FocusControl", focusControl, false, Enum.UserInputType.MouseButton1, Enum.UserInputType.Touch, Enum.UserInputType.Focus)

	mouse.Button1Down:Connect(function()
		shooting = true
		while shooting do
			wait(2)
			if gun.Ammo.Value > 0 then
				remote_event:FireServer(gun.Barrel.Position, gun.Handle.Orientation, offsetMouse(9))
				remote_event:FireServer(gun.Barrel.Position, gun.Handle.Orientation, offsetMouse(9))
				remote_event:FireServer(gun.Barrel.Position, gun.Handle.Orientation, offsetMouse(9))
				remote_event:FireServer(gun.Barrel.Position, gun.Handle.Orientation, offsetMouse(9))			
			gun.Ammo.Value = gun.Ammo.Value - 2
			shooting = false
			else
				         --nothing happens here so yeah....
			end

			

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

gun.Unequipped:Connect(function()
	shooting = false
end)

Thanks for reading.

You don’t have to declare the variable twice, UIS is not in the global scope. :face_with_raised_eyebrow:

The culprit is…

The lack of a debounce stopping it from firing is not there. There are many ways to implement the debounce. One of the common one is the os.clock(). The server only gives the ceiling of the rate of fire while the client responsive to its code.

1 Like

Use tick() or os.clock()
For example:

local debounce = os.clock()

event:Connect(function()
  if (os.clock()-debounce) > 1 then
   debounce = os.clock() -- reset
   print("Cant spam me :>")
 end
end)
6 Likes