How to make my gun automatic?

I have a gun and it works fine but you have to spam click it for the automatic weapons, I’ve attempted to make it automatic but it didn’t work too well.

(this isn’t all the code btw)

script.Parent.Activated:Connect(function()
		-- Automatic
		if automatic == true then
			repeat wait()
				if ammo > 0 and not reloading then
					script.Parent.GunShot:Stop()
					ammo = ammo - 1
					script.Parent.GunShot:Play()
					if mouse.Target.Parent:FindFirstChild("Humanoid") or mouse.Target.Parent.Parent:FindFirstChild("Humanoid") then
						if mouse.Target.Parent:IsA("Accessory") then
							script.Parent.Damage:FireServer(mouse.Target.Parent.Parent, damage)
						else
							script.Parent.Damage:FireServer(mouse.Target.Parent, damage)
						end
					end
				end
				wait(shoottime)
			until script.Parent.Deactivated
		else -- Non Automatic
			if shootdb == true then
				shootdb = false
				if ammo > 0 and not reloading then
					script.Parent.GunShot:Stop()
					ammo = ammo - 1
					script.Parent.GunShot:Play()
					if mouse.Target.Parent:FindFirstChild("Humanoid") or mouse.Target.Parent.Parent:FindFirstChild("Humanoid") then
						if mouse.Target.Parent:IsA("Accessory") then
							script.Parent.Damage:FireServer(mouse.Target.Parent.Parent, damage)
						else
							script.Parent.Damage:FireServer(mouse.Target.Parent, damage)
						end
					end
					wait(shoottime)
					shootdb = true
				elseif reloading == false then
					if canreload == true then
						reload()
						script.Parent.GunShot:Stop()
					end
				end
				
				while wait(0.1) do
					if canreload == true then
						textlabel.Text = (ammo).." / "..maxammo
					else
						textlabel.Text = ammo
					end
				end
			end
		end
	end)

These are well-functioning weapons that are beautiful, safe, and educational

Not really automatic if you have to spam click lol. Anyways to make it so you can hold down the mouse button to fire you first have to detect if the mouse button is held down and one way to do is to use IsMouseButtonPressed

Edit: Sorry for not being clear this is an example script, put this inside the Tool.Activated event to make it start detecting if the mouse is down when the tool is activated.

--Put this at the top of your script since it's a constant service
local UserInputService = game:GetService("UserInputService")
    

--Put this code below in Tool.Activated:Connect to detect mouse down continuously.
local pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)

while pressed do
--Check if pressed is released or not
pressed = UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)

--Do the fire bullet thing

end

1 Like

Wrong, pressed will be always false in your example, because you’re referring to UIS at the very beginning of your script.

Thus, usually when a player joins they don’t hold LPM.

Remember that a variable doesn’t automatically update.

Instead, I would do this in a while true do loop to constantly check if a player holds LPM.
(Yeah I know, while true do loops aren’t that efficient as they seem to be, but it’s just an example)

local uis = game:GetService("UserInputService");

coroutine.wrap(function()
    while true do
        if uis:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then
            -- fire the bullet
        end;

        wait(0.075);
    end;
end);

I am putting this loop in a coroutine, so it won’t yield and the code would run the rest.

You can remove it if you don’t need it.

2 Likes

Good catch, it will probably be confusing for newer scripters aiming to copy and paste my example script of an user input service script

Yeah true, so to add onto the topic I suggest an event based method to begin the detection only when the mouse button is pressed or released. This means connecting the script to a input began, input changed, and input ended but not necessarily all three.

This will prevent the code for running when it is not needed.

Please refer to the dev reference API and experimenting in game to see when these events will run.

You can just detect if the mouse button is held, not clicked.

1 Like

Thank you, I’ll try this and let ya know how it goes :+1:

Try this function

local tool = script.Parent
tool.Equipped:Connect(function(mouse)
local Pressed = false
print(Pressed)

mouse.Button1Down:Connect(function()
Pressed = true
print("Button1Down ", "Pressed ", Pressed)

end)

mouse.Button1Up:Connect(function()
Pressed = false
print("Button1Up ", "Pressed ", Pressed)

end)

end)

Colored balls gun automatic

The file contains all the details
Colored balls gun automatic.rbxl (25.9 KB)

– LocalScript

local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local tool = script.Parent
local Enable = false

tool.Equipped:Connect(function(mouse)

mouse.Button1Down:Connect(function()
Enable = true
local MachineEvent = script.Parent.MachineEvent
local Location = mouse.Hit.p
MachineEvent:FireServer(Location, Enable)
end)

mouse.Button1Up:Connect(function()
Enable = false
local MachineEvent = script.Parent.MachineEvent
local Location = mouse.Hit.p
MachineEvent:FireServer(Location, Enable)
end)

mouse.Move:Connect(function()
if Enable == true then
local MachineEvent = script.Parent.MachineEvent
local Location = mouse.Hit.p
MachineEvent:FireServer(Location)
end
end)

end)

– Script

local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local MachineEvent = script.Parent.MachineEvent
local ScriptEnable = nil
local ScriptLocation = nil

function buttonDown()
for i = 1,2 do

local number1 = math.random(1,255)	
local number2 = math.random(1,255)	
local number3 = math.random(1,255)	
	
local Ball = Instance.new("Part", workspace)
Ball.Name = "Ball"
Ball.Color = Color3.new(number1, number2, number3)
Ball.Material = Enum.Material.Neon
Ball.Shape = Enum.PartType.Ball
Ball.Transparency = 0
Ball.Anchored = false
Ball.CanCollide = false
Ball.TopSurface = Enum.SurfaceType.SmoothNoOutlines
Ball.BottomSurface = Enum.SurfaceType.SmoothNoOutlines
Ball.Size = Vector3.new(1, 1, 1)
Ball.CFrame = script.Parent.Handle.CFrame
Ball.formFactor = Enum.FormFactor.Custom

local bodyvelocity = Instance.new("BodyVelocity")
bodyvelocity.maxForce = Vector3.new(math.huge, math.huge, math.huge)
bodyvelocity.velocity = CFrame.new(script.Parent.Handle.CFrame.p, ScriptLocation).lookVector * 500	
bodyvelocity.Parent = Ball
	
wait(0.04)	
if ScriptEnable == true then	
   buttonDown()
end
end

end

local function onMachineFired(player, Location, Enable)
–print(player, Location, Enable)

ScriptLocation = Location
ScriptEnable = Enable
buttonDown()

end

MachineEvent.OnServerEvent:Connect(onMachineFired)

Doesn’t seem to be working, this is what I’ve got. (this is a local script inside the tool btw)

script.Parent.Activated:Connect(function()
		if ammo ~= 0 then
			if automatic == true then
				local uis = game:GetService("UserInputService");
				
				coroutine.wrap(function()
					while true do
						if uis:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then
							if ammo > 0 and not reloading then
								script.Parent.GunShot:Stop()
								ammo = ammo - 1
								script.Parent.GunShot:Play()
								if mouse.Target.Parent:FindFirstChild("Humanoid") or mouse.Target.Parent.Parent:FindFirstChild("Humanoid") then
									if mouse.Target.Parent:IsA("Accessory") then
										script.Parent.Damage:FireServer(mouse.Target.Parent.Parent, damage)
									else
										script.Parent.Damage:FireServer(mouse.Target.Parent, damage)
									end
								end
							end
							wait(shoottime)
						end;
						
						wait(shoottime);
					end;
				end);

Are there any errors or warnings in the output?
Try putting a print("cor") inside coroutine.wrap. Tell me if it prints that.

Put a print("1") after if uis:IsMouseButtonPressed statement,
and put a print("2") after if ammo > 0 statement.

Except a while true do loop and a coroutine, you could also use uis.InputBegan event I believe and check if the tool is equipped or connect that function whenever tool.Equipped fires and then disconnect it.

This would greatly improve performance of your script if would work.

If you wish to change coroutine and while loop to the event, put a print("Input:",input) instead of print("cor").
The input variable would be your parameter of the InputBegan event.

Tell me what do the statements print.

Good luck!

local mouseDown = false;
local mouse = client:GetMouse();
local uis = game:GetService("UserInputService");

mouse.Button1Up:Connect(function()
    mouseDown = false;
end)

uis.InputBegan:Connect(function(inp, gpe)
    if inp.UserInputType == Enum.UserInputType.MouseButton1 and not gpe then
        mouseDown = true;
        while mouseDown do
            -- your code goes here
        end
    end
end)

As long as mouseDown boolean is true, the while loop will run your code forever.

1 Like