How would i change a semi gun into an automatic?

okay, ill try that. i hope it works!

while shooting do
	if gun.Ammo.Value > 0 then
		gun.Ammo.Value -= 1
	else
		-- empty play
	end
	task.wait()
end

It seems like your a newbie to developing. Let me know if you have issues understanding. I can guide you.

it made my whole roblox studio almost crash, also the ammo went from 33/33 to -11k in a second, i will never fix that bruh.

oooooohhhh, yeah i forgot about the wait statement, no wonder it crashed.

okay ima try this


			gun_sound:Play()
				gun.Ammo.Value -= 1
				end
		else

			empty_sound:Play()

		end
task.wait(0.1)
		end)

wow, still crashes, i swear to god, how do people make the switches (automatic pistols)

Are you putting the “task.wait(0.1)” inside the loop?

i did the thing crypt told me to do

while shooting do
	if gun.Ammo.Value > 0 then
		gun.Ammo.Value -= 1
	else
		-- empty play
	end
	task.wait()
end

Try adjusting the duration, see if that will fix it.


		end
task.wait(0.5)
		end)

it still crashes, its probablly about the task.wait placement or the whole script.

I have a feeling this is because of the fired server, try this to see if it outputs a warning

local gun = script.Parent

local gun_sound = game.ReplicatedStorage["Gun shot"]

local empty_sound = game.ReplicatedStorage.clip_empty

local reload_sound = game.ReplicatedStorage.Reload

local player = game.Players.LocalPlayer

local clipSize = gun.Ammo.Value

local ammo = gun.Ammo

local shooting = false

local equipped = false



--UserInputService Setup

local userInput = game:GetService('UserInputService')



--Mouse Icon

local mouse = game.Players.LocalPlayer:GetMouse()



--Remote Event Setup



local ReplicatedStorage = game:GetService("ReplicatedStorage")

local remoteEvent = ReplicatedStorage:WaitForChild('ShotEvent')



--Checks if Mouse is clicked



gun.Equipped:Connect(function(mouse)



	player.PlayerGui.ScreenGui.Ammo.Visible = true

	player.PlayerGui.ScreenGui.Ammo.Text = 'Ammo: ' .. tostring(ammo.Value) .. ' / ' .. tostring(gun.MaxAmmo.Value)



	mouse.Button1Down:Connect(function()
               while shooting do
		if gun.Ammo.Value > 0 then

                          local success, err = pcall(function()

				remoteEvent:FireServer(gun.Handle.Position, gun.Handle.Orientation, mouse.Hit.p)

				gun_sound:Play()
gun.Ammo.Value -= 1
end)
if success then
print("fired")
else
warn(err)
end
		else

			empty_sound:Play()

		end
         task.wait(0.5)
end

	end

)

	mouse.Button2Down:Connect(function()



		local camera = game.Workspace.CurrentCamera



		camera.FieldOfView = 40



	end)



	mouse.Button2Up:Connect(function()



		local camera = game.Workspace.CurrentCamera



		camera.FieldOfView = 70



	end)



end)



-- Unequip gun



gun.Unequipped:Connect(function()

	player.PlayerGui.ScreenGui.Ammo.Visible = false

end)





--Checks if the letter R is pressed to reload



userInput.InputBegan:Connect(function(input, gameProcessed)



	if not gameProcessed then

		if input.UserInputType == Enum.UserInputType.Keyboard then

			local keycode = input.KeyCode

			if keycode == Enum.KeyCode.R then

				if gun.Ammo.Value < clipSize and gun.MaxAmmo.Value > 0 then

					reload_sound:Play()

					reload_sound.Ended:Wait()

					if gun.MaxAmmo.Value - (clipSize - gun.Ammo.Value) >= 0 then

						gun.MaxAmmo.Value = gun.MaxAmmo.Value - (clipSize - gun.Ammo.Value)

						gun.Ammo.Value = clipSize

					else

						gun.Ammo.Value = gun.Ammo.Value + gun.MaxAmmo.Value

						gun.MaxAmmo.Value = 0

						player.PlayerGui.ScreenGui.Ammo.Text = 'Ammo: ' .. tostring(ammo.Value) .. ' / ' .. tostring(gun.MaxAmmo.Value)

					end



				end

			end

		end

	end

end)



-- Update ammo GUI



ammo.Changed:Connect(function()

	player.PlayerGui.ScreenGui.Ammo.Text = 'Ammo: ' .. tostring(ammo.Value) .. ' / ' .. tostring(gun.MaxAmmo.Value)
end)

it doesn’t output anything, the gun doesn’t even shoot anymore.

Assuming the gun model you used was the “realistic gun” on your profile, I put it in roblox studio and recoded it. Is this what you anticipated?

wrong video sorry, it’s fixed now

robloxapp-20240106-1832412.wmv (2.5 MB)

You could use the UserInputService to detect if the mouse button is pressed.

something like:

local uis = game:GetService("UserInputService")

tool.Activated:Connect(function()
    repeat
        --shooting code
        wait(0.1) --shooting cooldown
        if not uis:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then break end
    until
        not uis:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) --this line will check if the given mouse button, MouseButton1, is being held or not.
end)

I have used a similar system before, and it has worked for me.

yes i used the realistic gun thingy but its really old, the script im using right now is alot more modified.

Looping outside of the functions.
Creating a new loop for everytime you fire the gun will just cause lag.

local IsShooting = false; -- to determine whether you can fire or not

Tool.Activated:Connect(function() -- fire when the weapon is activated
    IsShooting = true;
end)

Tool.Deactivated:Connect(function() -- fire when the weapon is deactivated
    -- this will not fire until you let go of your button
    IsShooting = false;
end)

while true do
    if IsShooting then
        -- fire if you are shooting
    else
        -- stops shooting
    end
    task.wait(Firerate) -- yield time for each activation
end

I believe there is more efficient way to doing this, so you dont have to create a loop for every weapon, however I still need to figure that out.

Spawn a separate thread that handles the firing when the tool is activated and cancel the thread when deactivated.

local fireThread = nil

local function CanFire()
	-- Returns true if we can shoot right now, e.g. we have enough ammo
end

mouse.Button1Down:Connect(function()
	fireThread = task.spawn(function()
		while task.wait(FIRERATE) do
			
			if not CanFire() then
				-- Skip this fire attempt and wait for the next one
				continue
			end
			
			-- Fire server, reduce ammo, etc.
		end
	end)
end)

mouse.Button1Up:Connect(function()
	if fireThread then -- Check if we're firing
		task.cancel(fireThread) -- Stops the while loop
		fireThread = nil
	end
end)

Here’s some code I use in my FPS Projects structured for your reference.
Try dropping it directly into an empty tool and mess around with it before putting it to use.

-- // Services
local RunService = game:GetService("RunService")

-- // References
local Tool = script.Parent

-- // Settings
local mag_ammo, reserve_ammo = (30), (30 * 100)
local fire_rate = 800 -- RPM (Rounds Per Minute)

-- // Variables
local trigger_down = false

local next_fire_time = 0

local fire_delay = 1 / (fire_rate / 60)

local fire_mode = "FULL_AUTO"

-- // Functions
local function Fire()
	mag_ammo -= 1
	
	print("Pew!")
	print(mag_ammo.." / "..reserve_ammo)
end

local function OnToolActivated()
	trigger_down = true
end

local function OnToolDeactivated()
	trigger_down = false
end

local function OnCameraUpdate()
	
	-- // Shoot Code
	if (trigger_down and mag_ammo > 0 and time() > next_fire_time) then
		next_fire_time = time() + fire_delay

		if (fire_mode == "SEMI_AUTO") then
			Fire()
			trigger_down = false

		elseif (fire_mode == "FULL_AUTO") then
			Fire()

		elseif (fire_mode == "BURST_AUTO") then
			next_fire_time = time() + fire_delay + .3
			for i = 1, 3, 1 do
				if (mag_ammo < 1) then break end
				Fire()
				task.wait(fire_delay)
			end
			trigger_down = false

		end
	end
	----------------
	
end

-- // Events
Tool.Activated:Connect(OnToolActivated)
Tool.Deactivated:Connect(OnToolDeactivated)

RunService:BindToRenderStep("camera_update", Enum.RenderPriority.Camera.Value, OnCameraUpdate)

It Supports SEMI, FULL, and BURST. Hope this helps!

3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.