I am trying to make it so when I hold the mouse button down it shoots, but when I click my mouse faster than the wait timer in the loop it makes a new loop
this is what happens
here is my code
function shoot()
if magazine > 0 then
if firing then
local mousePosition = mouse.Hit.Position
fireEvent:FireServer(mousePosition)
magazine -= 1
end
else
if reloading == false then
reloading = true
magazine = 0
wait(reloadtime)
magazine = magazinesize
reloading = false
end
end
end
mouse.Button1Down:Connect(function()
if firing == false then
firing = true
while firing do --this is the loop that errors
shoot()
wait(1 / firerate)
end
end
end)
mouse.Button1Up:Connect(function()
firing = false
end)
What exactly do you mean by clicking âfaster than the wait timerâ, do you mean clicking faster than âwait(X)â or do you mean clicking faster than any timer that is in the loop? (For example, if you have a script with this loop: while true do ⌠end
Do you mean clicking faster than the loop?)
I have figured out the problem heres the new modified code
local Shooting = true
local magazine = 5
local reloadtime = 1
local firerate = 1
function shoot()
if magazine > 0 then
if firing then
local mousePosition = mouse.Hit.Position
fireEvent:FireServer(mousePosition)
magazine -= 1
wait(reloadtime)
I have fixed the loop and made it way more easier to read
The issue its not the loop specifically, its about the debounce âfiringâ. More than one loop is created when you click fast, not related with the wait() time in the script. Once you ButtonUP, the debounce is open again to accept inputs again, so you are triggering it many times causing multiple loops.
Then the way the while loop is using to break, while firing do, makes it to wait wait(1 / firerate), causing it wont break in the exact moment the ButtonUP happens.
If this already Client sided which is not exactly recomended to handle the magazine player has⌠You could use a RunService step connection calling the shoot function when ButtonDown, and disconnect it when ButtonUP, to âstop the loopâ in the exact moment the ButtonUP happens.
This is specifically for your current approach, of Client sided handling magazine and stuff. Its just an edited version of your script using RunService check and splitting functions.
local Players = game:GetService("Players")
local RS = game:GetService("RunService")
local player = Players.LocalPlayer
local mouse = player:GetMouse()
-- 2 bullets per second, one each 0.5 seconds
local firerate = 0.5
-- bullets in gun
local magazine = 7
-- default size of magazine
local magazinesize = 7
-- reload debounce and time
local reloading = false
local reloadtime = 4
-- player's holding button time
local fireTime = 0
-- RunService step connection
local fireConn
-- Reload function
local function Reload()
warn("Reloading")
task.wait(reloadtime)
print("Reload done")
magazine = magazinesize
reloading = false
end
-- Shooting function
function Shoot()
if magazine > 0 then
warn("shoot")
local mousePosition = mouse.Hit.Position
fireEvent:FireServer(mousePosition) -- Your server call
magazine -= 1
print("remaining mag:", magazine)
else
print("mag empty")
reloading = true
fireConn:Disconnect()
Reload()
end
end
mouse.Button1Down:Connect(function()
if not reloading then
-- THE "LOOP" connection. A RunService step
fireConn = RS.RenderStepped:Connect(function(d)
fireTime += d -- delta progress
if fireTime >= (1*firerate) then -- if enough time since last shoot, shoot again
fireTime = 0
Shoot()
end
end)
Shoot() -- First shoot when holding button
else
warn("cant shoot while reloading")
end
end)
mouse.Button1Up:Connect(function()
fireConn:Disconnect() -- Disconnect the "loop" inmediately
end)
*It has prints and warns for you to check it in Output
local mouse = game.Players.LocalPlayer:GetMouse()
local mag = {
["bullets"] = 0,
["capacity"] = 10
}
local reloading = false
local m1down = false
local shotsPerSecond = 15
local reloadBulletsPerSecond = 1.2
mouse.Button1Down:Connect(function() reloading = false m1down = true end)
mouse.Button1Up:Connect(function() m1down = false end)
game:GetService("UserInputService").InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input.UserInputType == Enum.UserInputType.Keyboard then
if input.KeyCode == Enum.KeyCode.R then
if mag.bullets < mag.capacity then
reloading = true
end
end
end
end)
local i = 0
local lastShot = os.clock()
local lastBulletReload = os.clock()
while true do
if reloading and (os.clock() - lastBulletReload) >= (1/reloadBulletsPerSecond) then
if (mag.bullets < mag.capacity) then
mag.bullets += 1
print("reload click "..mag.bullets.."/"..mag.capacity)
lastBulletReload = os.clock()
else
reloading = false
end
end
if (m1down and not reloading and (os.clock() - lastShot) >= (1/shotsPerSecond)) then
if (mag.bullets > 0) then
mag.bullets -= 1
print("pew "..mag.bullets.."/"..mag.capacity)
lastShot = os.clock()
if mag.bullets == 0 then
reloading = true
end
else
reloading = true
end
end
i += 1
if (i > 300) then wait() i = 0 end
end