I’m currently working on a laser gun that fires if the player holds the mouse button down, stopping when they let go. I wrote a while wait loop inside a few event functions but the gun continues to fire even after letting go of the button. here’s my script:
gun.Equipped:Connect(function(mouse)
mouse.Button1Down:Connect(function()
fireGun(mouse)
while wait(debounce) do
if mouse.Button1Down then
fireGun(mouse)
print("Button down.")
else
break
end
end
end)
end)
local debounce = false
gun.Equipped:Connect(function(mouse)
mouse.Button1Down:Connect(function()
fireGun(mouse)
if mouse.Button1Down and debounce == false then
debounce = true
fireGun(mouse)
print("Button down.")
task.wait(3) -- set 3 to your cooldown time
debounce = false
end
end)
end)
here is the dev hub page on debounces you do not need a while loop on debounces
This doesn’t really work for what I’m applying the debounce to…
Whenever the mouse button is held, the script does nothing. The only thing this edit does is print when I click my mouse button if 3 or more seconds have passed.
local debounce = false
gun.Equipped:Connect(function(mouse)
mouse.Button1Down:Connect(function()
if mouse.Button1Down and not debounce then
debounce = true
fireGun(mouse)
print("Button down.")
delay(3, function()
debounce = false
end)
end
end)
end)
This will not hold up the event handler. And I corrected your error.
I would not use the mouse, and instead, use UserInputService.
Documentation on that clearly exists for mouse clicks but I’m too lazy to pull it up at the moment. Just so you know, you don’t have to worry about it being deprecated anytime soon, unlike the Mouse object.
local function fireGun(mouse)
local laser = Ray.new(barrel.CFrame.Position, (mouse.Hit.Position - barrel.CFrame.Position).unit * 300)
local hitPart, hitPos = game.Workspace:FindPartOnRay(laser, char, false, true)
local laserPart = Instance.new("Part", game.Workspace)
laserPart.BrickColor = BrickColor.new("Really blue")
laserPart.FormFactor = "Custom"
laserPart.Material = "Neon"
laserPart.Transparency = 0.2
laserPart.Anchored = true
laserPart.CanCollide = false
local distance = (barrel.CFrame.Position - hitPos).Magnitude
laserPart.Size = Vector3.new(0.2, 0.2, distance)
laserPart.CFrame = CFrame.new(barrel.CFrame.Position, hitPos) * CFrame.new(0, 0, -distance)
sound.Volume = SFXvol
sound:Play()
debris:AddItem(laserPart,0.1)
if hitPart then
local humanoid = hitPart.Parent:FindFirstChild("Humanoid")
if not humanoid then
humanoid = hitPart.Parent.Parent:FindFirstChild("Humanoid")
end
if humanoid then
if hitPart.Name == "Head" then
humanoid:TakeDamage(headshot)
else
humanoid:TakeDamage(damage)
end
end
end
end
local uis = game:GetService("UserInputService")
local mouse = game.Players.LocalPlayer:GetMouse()
local fired = false
gun.Equipped:Connect(function()
uis.InputBegan:Connect(function(key)
if key.UserInputType == Enum.UserInputType.MouseButton1 then
if fired == false then
fired = true
while fired do
wait()
fireGun(mouse)
end
end
end
end)
uis.InputBegan:Connect(function(key)
if key.UserInputType == Enum.UserInputType.MouseButton1 then
fired = false
end
end)
end)
Do not use this. After equipping, the event will be connected. After equipping again, it will have two connections. Just have an “equipped” variable and put a statement in the InputBegan and InputEnded connections like if not equipped then return end or something.