Gun Reloads Once

I’m making a gun system, my gun shoots just fine, aims fine, etc. My issue is that it only reloads once, then it doesn’t reload anymore after that. I’m trying to make it so you can completely run out of ammo. So here’s an example.
16/30 Bullets
16 being the ammo thats being shot, 30 being the mag size
after i reload, it should be 30/14
Since it’s back to 30 bullets to shoot, and 14 is leftover in the mag for the next reload, the next reload would change from 0/14 to 14/0. Any fixes?

local runService = game:GetService("RunService")
local userinputservice = game:GetService("UserInputService")

local player = game.Players.LocalPlayer
local char = workspace:WaitForChild(player.Name)
local humanoid = char:WaitForChild("Humanoid")

local mouse = player:GetMouse()

local cam = workspace.Camera

local main = script.Parent:WaitForChild("Handle")

--variables
local walkf = false
local equipped = false
local ammo = script.Parent.Ammo
local mag = 15
local clipSize = script.Parent.Ammo.Value
local reloadTime = 2.19

local gui = script.Ammo

script.Parent.Equipped:Connect(function()
	local arms = game.ReplicatedStorage.M4A1:Clone()
	userinputservice.MouseIconEnabled = false
	arms.Parent = workspace

	local walkanim = arms.AnimationController:LoadAnimation(arms.Walk)

	local idleAnim = arms.AnimationController:LoadAnimation(arms.Idle)
	idleAnim:Play() -- TO make sure the idle animation is ready to play after the equip animation

	local equiptAnim = arms.AnimationController:LoadAnimation(arms.Equip)

	local runAnim = arms.AnimationController:LoadAnimation(arms.Run)

	local shootAnim = arms.AnimationController:LoadAnimation(arms.Semi)

	local reloadAnim = arms.AnimationController:LoadAnimation(arms.Reload)

	--local aimAnim = arms.AnimationController:LoadAnimation(arms.Aiming)

	equipped = true
	equiptAnim:Play()
	arms.Parent = workspace
	main.Transparency = 1

	if equipped then
		gui = script.Ammo:Clone()
		gui.Parent = player.PlayerGui
	end


	local function RefreshGui()
		gui.Frame.Ammo.Text = clipSize
		gui.Frame.Mag.Text = script.Parent.MaxAmmo.Value
	end



	wait(0.1)-- the time for the arms to load or clone.

	RefreshGui()

	local SwayEffect = 0.75
	local SwayCFrame = CFrame.new()
	local LastCameraCFrame = CFrame.new()

	runService.RenderStepped:Connect(function() -- this makes the arms more realistic when you rotate the camera.

		local Rotation = workspace.CurrentCamera.CFrame:ToObjectSpace(LastCameraCFrame)
		local X,Y,Z = Rotation:ToOrientation()
		SwayCFrame = SwayCFrame:Lerp(CFrame.Angles(math.sin(X) * SwayEffect, math.sin(Y) * SwayEffect, 0), 0.1)
		LastCameraCFrame = workspace.CurrentCamera.CFrame

		if arms.PrimaryPart then
			arms:SetPrimaryPartCFrame(cam.CFrame *SwayCFrame * CFrame.new(0,-0.5,-1))
		end
	end)

	humanoid.Running:Connect(function(Speed)
		if not walkf then
			walkf = true
			if Speed > 0 then
				print("20202")
				walkanim.Looped = true
			--	if aimAnim.IsPlaying == true then
				--	aimAnim:Play()
				else
					walkanim:Play()
				end
				walkf = false
			else
				print("232323")
				walkanim:Stop()
				walkf = false
			end
		--end
	end)
	--running

	local RunAnimation = Instance.new('Animation')
	RunAnimation.AnimationId = 'rbxassetid://6466290860'
	RAnimation = humanoid:LoadAnimation(RunAnimation)

	Running = false

	local walk = char.HumanoidRootPart:FindFirstChild("Running")
	walk.SoundId = "rbxassetid://4416041299"
	walk.PlaybackSpeed = 1
	walk.Volume = 0.8

	local jump = char.HumanoidRootPart:FindFirstChild("Jumping")
	jump.SoundId = "rbxassetid://379482972"
	jump.PlaybackSpeed = 1
	jump.Volume = 0.5

	function Handler(BindName, InputState)
		if InputState == Enum.UserInputState.Begin and BindName == 'RunBind' then
			Running = true
			humanoid.WalkSpeed = 15
			walk.PlaybackSpeed = 1.45
			walk.Volume = 1.3
		elseif InputState == Enum.UserInputState.End and BindName == 'RunBind' then
			Running = false
			if RAnimation.IsPlaying then
				RAnimation:Stop()
				runAnim:Stop()
			end
			walkf = false
			humanoid.WalkSpeed = 8
			walk.PlaybackSpeed = 1
			walk.Volume = 0.8 
			runAnim:Stop()
		end
	end

	humanoid.Running:connect(function(Speed)
		if Speed >= 6 and Running and not RAnimation.IsPlaying then
			walkf = true
			RAnimation:Play()
			runAnim:Play()
			humanoid.WalkSpeed = 15 -- change your custom run speed
			walk.PlaybackSpeed = 1.45-- custom speed for walk sound
			walk.Volume = 1.3-- default volume for walk sound
			walkanim:Stop()
		elseif Speed >= 6 and not Running and RAnimation.IsPlaying then
			walkf = false
			RAnimation:Stop()
			humanoid.WalkSpeed = 8 -- default speed
			walk.PlaybackSpeed = 1 -- default speed for walk sound
			walk.Volume = 0.8 -- default volume for walk sound
			runAnim:Stop()
		elseif Speed < 6 and RAnimation.IsPlaying then
			walkf = false
			RAnimation:Stop()
			humanoid.WalkSpeed = 8  -- default speed
			walk.PlaybackSpeed = 1  -- default speed for walk sound
			walk.Volume = 0.8 -- default volume for walk sound
			runAnim:Stop()
		end
	end)

	humanoid.Changed:connect(function()
		if humanoid.Jump and RAnimation.IsPlaying then
			RAnimation:Stop()
			walk.Volume = 0.8-- default volume for walk sound
			runAnim:Stop()
			idleAnim:Play()
		end
	end)


	local reloading = false
	local canshoot = true
	local shootpart = arms.Gun.Handle.MuzzleFlash
	local cursor = player:GetMouse()
	local reloadTime = 2.19


	local function Shoot()
		script.Parent.OnShot:FireServer(cursor.Hit.Position, shootpart.Position)
	--	if aimAnim.IsPlaying == true and mouse.Button2Down then
		--	script.Parent.Handle.Shot:Play()
		ammo.Value = ammo.Value - 1
			RefreshGui()
		--	aimAnim:Play()
		--elseif aimAnim.Stopped == true then
			shootAnim:Play()
		--	ammo = ammo -1
			script.Parent.Handle.Shot:Play()
			RefreshGui()
		--end
		--[[script.Parent.OnShot:FireServer(cursor.Hit.Position, shootpart.Position)
		shootAnim:Play()
		ammo = ammo - 1
		script.Parent.Handle.Shot:Play()
		RefreshGui()
		print("Shot")]]--
	end

	local function reload()
		reloadAnim:Play()
		if script.Parent.MaxAmmo.Value - (clipSize - script.Parent.Ammo.Value) then
			script.Parent.MaxAmmo.Value = script.Parent.MaxAmmo.Value - (clipSize - script.Parent.Ammo.Value)
			script.Parent.Ammo.Value = clipSize
		else 
			script.Parent.Ammo.Value = script.Parent.Ammo.Value + script.Parent.MaxAmmo.Value
			script.Parent.MaxAmmo.Value = 0
		end
		RefreshGui()
		print("Reloading")
	end
	script.Parent.Activated:Connect(function()
		if canshoot and not reloading then
			if script.Parent.Ammo.Value <= script.Parent.MaxAmmo.Value and script.Parent.Ammo.Value > 0 then
				canshoot = false
				Shoot()
				for i,v in pairs (shootpart:GetChildren()) do
					if v:IsA("SpotLight") or v:IsA("ParticleEmitter") then
						v.Enabled = true
						print("Shot")
						wait(0.05)
						v.Enabled = false 
					end
				end
				wait(0.3)
				canshoot = true
			elseif ammo == 0 then
				reload()
				reloading = true
				canshoot = false
				wait(reloadTime)
				reloading = false
				canshoot = true
			end
		end
	end)
	userinputservice.InputBegan:Connect(function(input, gameProcessed)
		if input.KeyCode == Enum.KeyCode.R then
			if script.Parent.Ammo.Value < script.Parent.MaxAmmo.Value then
				if canshoot and not reloading then
					canshoot = false
					reloading = true
					reload()
					wait(reloadTime)
					canshoot = true
					reloading = false
				end
			else 
				return
			end
		end
	end)

	local function AimIn()
		idleAnim:Stop()
		--aimAnim:Play()
		game.Workspace.Camera.FieldOfView = 50
	end

	local function AimOut()
		--aimAnim:Stop()
		idleAnim:Play()
		game.Workspace.Camera.FieldOfView = 70
	end

	mouse.Button2Down:Connect(function()
		local char = player.Character
		local equippedTool = char:FindFirstChild("M4A1")

		if equippedTool then
			print("equipped tool")
			AimIn()
		else
			print("No Tool Equipped")
		end
	end)
	mouse.Button2Up:Connect(function()
		local char = player.Character
		local equippedTool = char:FindFirstChild("M4A1")

		if equippedTool then
			print("equipped tool")
			AimOut()
		else
			print("No Tool Equipped")
		end
	end)

	game:GetService('ContextActionService'):BindAction('RunBind', Handler, true, Enum.KeyCode.LeftShift)

	script.Parent.Unequipped:Connect(function()
		userinputservice.MouseIconEnabled = true
		equipped = false
		if not equipped then
			gui:Destroy()
		end
		arms:Destroy()
	end)
end)
2 Likes

It’s hard to tell without the gun, but try printing this line:

print("confusing line", script.Parent.MaxAmmo.Value - (clipSize - script.Parent.Ammo.Value))

Place it at the beginning of your reload() function.

1 Like


This popped up.

You’re not making a comparison in this line, just giving the if statement a number by itself

if script.Parent.MaxAmmo.Value - (clipSize - script.Parent.Ammo.Value) then

So, how do I fix it? I’m not too big of a scripter.

1 Like

Just replace the first - with a >

if script.Parent.MaxAmmo.Value > (clipSize - script.Parent.Ammo.Value) then

I’m assuming you want to check if the leftover ammo is more than the amount of ammo that is going into the mag

1 Like

But it still won’t let me reload more than once

1 Like

Sometimes you just have to print things to see what they are doing.

Your last print said the value was “27”

I don’t know if that is right or not, but you might if you try printing more things.

Print every line of the reload() function and try to understand what it is doing.

If everything checks out, then print other things until you figure out where the error exists.

1 Like

Change ammo to ammo.Value here, ammo is the IntValue instance and not the number itself

elseif ammo.Value == 0 then
1 Like
script.Parent.Activated:Connect(function()
		if canshoot and not reloading then
			if script.Parent.Ammo.Value <= script.Parent.MaxAmmo.Value and script.Parent.Ammo.Value > 0 then
				canshoot = false
				Shoot()
				for i,v in pairs (shootpart:GetChildren()) do
					if v:IsA("SpotLight") or v:IsA("ParticleEmitter") then
						v.Enabled = true
						print("Shot")
						wait(0.05)
						v.Enabled = false 
					end
				end
				wait(0.3)
				canshoot = true
			elseif ammo.Value == 0 then
				print("Reloading")
				reload()
				reloading = true
				canshoot = false
				wait(reloadTime)
				reloading = false
				canshoot = true
			end
		end
	end)

It’s still not working. Did I do the correct part?

Did you print ammo to see what it was before you changed it?

In scripting it’s best not to assume, just print and see if it is wrong before you change it.

print(ammo)

1 Like

Where would I put that in the script?

Just before it in this case.

print(ammo)
elseif ammo == 0 then

image
so right below the canshoot?

1 Like

Yes, that is the place to put it.

1 Like

image

When I shoot, it prints ammo. When I press R, the other stuff pops up

1 Like

Then try what Azi_Vee suggested.

Change ammo to be ammo.Value and try again. See if you get a number instead of a word.

Change script.Parent.MaxAmmo.Value to clipSize, you were comparing it to the bullets in the reserve rather than checking if there have been bullets shot from the current clip

if script.Parent.Ammo.Value < clipSize then
1 Like

image
I do have it set to

elseif ammo.Value == 0 then