So, I'm trying to get an automatic mode for the gun working. Fires perfectly fine with automatic false. To make things simpler, I'm cutting it to the part of the script that is having trouble.
When automaticFire is false, it fires fine. When it's false, it won't fire a single shot, and doesn't output any errors.
If it's important to fixing, fireRate is set to 0.1.
tool.Equipped:connect(function(mouse) print("Tool equipped!") --Trigger pulled mouse.Button1Down:connect(function() if automaticFire then mouseDown = true else fireBullet() end end) --Trigger released mouse.Button1Up:connect(function() if automaticFire then mouseDown = false end end) while mouseDown and automaticFire do fireBullet() wait(fireRate) end end)
Let's look through this code and understand what it's doing. I presume local variables automaticFire
, mouseDown
, tool
, and fireRate
are defined before the code you provided, as well as the fireBullet
function.
tool.Equipped:Connect(function(mouse) print("Tool equipped!")
This is pretty simple. It connects a function to the Equipped
event of the tool. It receives in a mouse
parameter. Then it prints "Tool equipped!". Everything is working so far.
Now we have this:
mouse.Button1Down:Connect(function() if automaticFire then mouseDown = true else fireBullet() end end)
So we take the mouse we were given, connect to its Button1Down
event, and then do one of two things. If automaticFire is true, we set mouseDown
to true, otherwise, we call the fireBullet
function. So far so good.
Next is this:
mouse.Button1Up:Connect(function() if automaticFire then mouseDown = false end end)
Here we connect to the mouse's Button1Up
event a function that will reset mouseDown
to false if automaticFire
is true. Still working.
Finally, we have this:
while mouseDown and automaticFire do fireBullet() wait(fireRate) end end)
This would normally be fine. However, in this case, the conditions are checked once, when the tool activates, and since mouseDown
isn't true to start with, it will skip the loop and never fire. Not what we want.
To fix this, we need to put this loop somewhere that will run every time we might fire. How about the Button1Down
event connection?
mouse.Button1Down:Connect(function() if automaticFire then mouseDown = true while mouseDown and automaticFire do fireBullet() wait(fireRate) end else fireBullet() end end)
Now since once we get to the loop, we know both mouseDown
and automaticFire
are true, it will enter the loop and continue firing.
Now there are two minor things we can change. First, in the loop, since we are in the if statement that checks if automaticFire
is true, we don't have to check that in the loop. Second, if fireRate
is given in rounds per minute or a similar measure (for example, 500 rpm), it will wait that number in seconds (500 seconds). Not exactly what we want. We can instead take the reciprocal of that number to get minutes per round, then multiply that by 60 to get seconds per round, which is how long we want to wait.
mouse.Button1Down:Connect(function() if automaticFire then mouseDown = true while mouseDown do fireBullet() wait(60/fireRate) end else fireBullet() end end)
Note that there is a minimum wait time, so you may only be firing 30 rounds per minute instead of the number you expect.