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.