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

So this is the script inside a tool:

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()
		shooting = true
		if gun.Ammo.Value > 0 then
			while shooting do 
			remoteEvent:FireServer(gun.Handle.Position, gun.Handle.Orientation, mouse.Hit.p)

			gun_sound:Play()
				gun.Ammo.Value -= 1
				end
			task.wait(0.5)
		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

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 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)

but for some reason when i activate it, the studio just freezes for a few seconds.

4 Likes

Have you tried doing it in the Roblox client? Also, spacing out your lines makes it much harder for you to understand what is wrong about your script.

@Mob1leN0OB

1 Like

It could be because your while loop doesn’t contain a waiting line. After indenting the lines, here’s your code:

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

	gun_sound:Play()
	gun.Ammo.Value -= 1
end
task.wait(0.5)

The task.wait(.5) is outside the loop, so the loop will run until shooting is not True. By unclicking with the mouse, the shooting variable becomes False, which will stop this loop, that’s why you’ve been lagging.

Simply by putting a wait line in the loop, I think it should fix it.

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

	gun_sound:Play()
	gun.Ammo.Value -= 1
    task.wait(.5)
end

Also try not to separate every line, try to group code by content. At a new content, you should make an empty line, but those lines you made aren’t necessary.

Okay ill try that real quick, i hope it works.

It kind of works, but when i click once it keeps shooting even though i stopped holding, and after it reaches 0 ammo it still shoots, it still shoots after i got -4 ammo, ima show u what i mean.

by the way, sorry if the recording is laggy. im on an 4 yo laptop with windows 10.

bro the recording is so bad that there was still like 20 seconds of footage but it just cut it.

It’s because even though you’ve checked if the ammo is positive, but it was a simple ‘if’ statement. You want to break the loop when the ammo is 0. If you don’t break the loop, the ammo will eventually go under 0.

if gun.Ammo.Value > 0 then --You checked it yeah, but
	while shooting do --If ammo is 0, this loop will still run, because it doesn't check ammo
	    remoteEvent:FireServer(gun.Handle.Position, gun.Handle.Orientation, mouse.Hit.p)

	    gun_sound:Play()
	    gun.Ammo.Value -= 1
	end
	task.wait(0.5)

So I think it should fix it:

while shooting and gun.Ammo.Value >0 do 
    task.wait(.5)
	remoteEvent:FireServer(gun.Handle.Position, gun.Handle.Orientation, mouse.Hit.p)

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

i get
“Players.Mob1leN0OB.Backpack.SWITCH.AutoScript:66: Expected ‘end’ (to close ‘function’ at line 57), got ‘else’; did you forget to close ‘do’ at line 59?”

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()
		shooting = true
		while shooting and gun.Ammo.Value >0 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

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 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)

I removed an ‘else’ statement because the problem wasn’t with that, you can put it back or wait a little

oh okay… wait give me a small second real quick.

			while shooting and gun.Ammo.Value >0 do 
            task.wait(.5)
			remoteEvent:FireServer(gun.Handle.Position, gun.Handle.Orientation, mouse.Hit.p)

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

The problem with not indenting the lines properly is because I don’t understand how this piece of code works

1 Like

Okay i kinda made the script easier to understand:

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()
shooting = true
if gun.Ammo.Value > 0 then
while shooting do 
remoteEvent:FireServer(gun.Handle.Position, gun.Handle.Orientation, mouse.Hit.p)
gun_sound:Play()
gun.Ammo.Value -= 1
end
task.wait(0.5)
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
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 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)
1 Like

tbh idk what im supposta do now lol.

1 Like

If you unclick with your weapon and to stop, you want shooting to be False.

To make it somewhat easy, I’d make a boolValue inside the gun called shooting, and have a 2nd script, which would set shooting to True and False, depending on the mouseEvents.

yeah, when i stop holding the button just stop shooting.

Even after i unequip the gun it still shoots wherever i aim, lol.

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()
		shooting = true
		if gun.Ammo.Value > 0 then
		while shooting  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
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 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)

Make a shooting boolValue inside the gun, and add a localScript with this code in it:

mouse = game.Players.LocalPlayer:GetMouse()

mouse.Button1Down:Connect(function()
	script.Parent.Shooting.Value = true
end)
mouse.Button1Up:Connect(function()
	script.Parent.Shooting.Value = false
end)

And let shooting = script.Parent.Shooting in your other script.