Roblox studio freezing for a few seconds after clicking with tool equipped

To fix it, let’s drop the 2nd script idea. In your bigger script, if the mouse is down, it should fire the gun, so make it like

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)
	equipped = true
	shooting = true
	mouse.Button1Down:Connect(function()
		if gun.Ammo.Value > 0 then
			while gun.Ammo.Value > 1 and equipped do 
				task.wait(.5)
				remoteEvent:FireServer(gun.Handle.Position, gun.Handle.Orientation, mouse.Hit.p)

				gun_sound:Play()
				gun.Ammo.Value -= 1
			end
		else
			empty_sound:Play()
		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
	equipped = 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 and not shooting then shooting = true
				while not shooting do
					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
					task.wait(0.1) -- change this to your liking
				end
			end
		end
	end
end)

userInput.InputEnded:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.R then
		shooting = false
	end
end)

-- Update ammo GUI

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

And it should be the only script I think, hope it fixes it now.

okay so it actually works somehow, but i notice one more thing. If i click twice it fires two bullets like a burst weapon.

and yeah, it still goes through the ammo limit, it still shoots even though there is 0 ammo.

i think ill make it so the script gets disabled if theres 0 ammo and when i reload it gets enabled.

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)
	equipped = true
	shooting = true
	mouse.Button1Down:Connect(function()
		if gun.Ammo.Value > 0 then
			while gun.Ammo.Value > 1 and equipped do 
				task.wait(.5)
				remoteEvent:FireServer(gun.Handle.Position, gun.Handle.Orientation, mouse.Hit.p)

				gun_sound:Play()
				gun.Ammo.Value -= 1
			end
		else
			empty_sound:Play()
		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
	equipped = 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 and not shooting then shooting = true
				while not shooting do
					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
					task.wait(0.1) -- change this to your liking
				end
			end
		end
	end
end)

userInput.InputEnded:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.R then
		shooting = false
	end
end)

-- Update ammo GUI

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

if gun.Ammo.Value == 0 then
	script.Enabled = false
	print("0 ammo!")
end

okay so it kind of works, but if i still click alot the ammo can go to -20 and then stop shooting, and the reloading stops working. i keep thinking ill use a free model.

Can you maybe print out the gun.Ammo.Value inside the while loop? Also change it from gun.Ammo.Value > 1 to gun.Ammo.Value > 0

okay so when i shoot it prints

mouse.Button1Down:Connect(function()
		if gun.Ammo.Value > 0 then
			while gun.Ammo.Value > 0 and equipped do 
				print("shooting test")
				task.wait(.5)
				remoteEvent:FireServer(gun.Handle.Position, gun.Handle.Orientation, mouse.Hit.p)

We want to know what gun.Ammo.Value is, as that’s the one that contradicts our statement that ammo shouldn’t go under 0.

i forgot to mention, the gun keeps shooting even if i stop holding.

maybe disable the script when the gun is unequipped and enable it back when it is equipped

i already tried doing that but it won’t enabled back.

Make a 2nd script for that, because the disabled script wont reagate for equipping a tool.

okay so i fixed the thing in which if i stop holding it shoots, but now im having problems with enabling the gun and reloading system.

Just make a 2nd script, which checks if the gun is equipped, if yes, it enables the main script, if is is unequipped, it disables it.

okay i fixed that, the only thing left is fix the reloading system.

What’s the problem with it?
Did the reload work previously?

i click r and it doesn’t reload the weapon and it doesn’t play the sound, here’s the reload script:

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 and not shooting then shooting = true
				while not shooting do
					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
					task.wait(0.1) -- change this to your liking
				end
			end
		end
	end
end)

Did it work before? Maybe change while not shooting do to while shooting do?

yeah it worked before. Ill try the while shooting do thingy in a sec.

i think i fixed it, one more thing. could ya help me with enabling the script? cuz i tried the second script and after i stop shooting it just doesnt shoot, i gotta reequip the gun for it to work again.