Best way to make a ammo system for a game

Recently I have been making a gun game and I’ve made what I wanted but I tried making a gun system and I can’t seem to make one. My current idea is to make a int value and subtracting it for every shot. I would then check before each shot if the value is > than 0. I then used a local script and using user input services I would detect if R(the key to reload) is pressed and then set the value of the int value back to the desired number. However It doesn’t seem to work and I think the problem is that int values cannot be changed by local scripts. Is there a way to use my method or a different method to make a ammo system. I am a new scripter so if it is a simple fix I won’t be surprised.

Here is the script that makes the raycast

local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")

local RunService = game:GetService("RunService")
local Tool:Tool = script.Parent
local Handle = script.Parent.Handle
local u1 = script.Parent.Union
local u2 = script.Parent.Union2
local ShootPart = script.Parent.Part
local RemoteEvent = Tool:FindFirstChild("RemoteEvent")
local OnCooldown = false
local pe = ShootPart.ParticleEmitter
local sl = ShootPart.SpotLight
local chamber = script.Parent.Chamber
local dead = false
local plrs = game:GetService("Players")






local Do = {
	Damage = 18;
	Cooldown = 0.3;
	Visualize = true;
	ShootSound = "rbxassetid://5238024665";
}
while true do
	local Origin = ShootPart.Position
	wait(0.01)
	
	
	
	RemoteEvent.OnServerEvent:Connect(function(Player,Received)
		local leaderstats = Player.leaderstats
		local kills = leaderstats.Kills
	if not OnCooldown then
		if chamber.Value > 0 then	
		OnCooldown = true
		task.delay(Do.Cooldown,function()
			OnCooldown = false
		end)	
			chamber.Value = chamber.Value - 1
			local Direction = (Received.Position-Origin).Unit*3000
			local Raycast = workspace:Raycast(Origin,Direction)
			
	

		local Intersection = Raycast and Raycast.Position or Origin + Direction
		local Distance = (Origin - Intersection).Magnitude


		pe.Enabled = true
		sl.Brightness = 28
		wait(0.1)
		pe.Enabled = false
		sl.Brightness = 0
			

		if (Do.ShootSound ~= "" or Do.ShootSound ~= nil) then
			local Sound = Instance.new("Sound")
			Sound.SoundId = Do.ShootSound
			Sound.Volume = .65
			Sound.PlayOnRemove = true
			Sound.Parent = Handle
			Sound:Destroy()
		end

				if Raycast then
					local Hit:Part = Raycast.Instance
					local Humanoid = (Hit.Parent:FindFirstChildOfClass("Humanoid") or Hit.Parent.Parent:FindFirstChildOfClass("Humanoid"))

					if Humanoid and Humanoid.Parent ~= Player.Character then
						if Humanoid.Health > 0 then
							dead = false
							Humanoid:TakeDamage(Do.Damage)
							script["HitMarker Sound Effect"]:Play()

							if Humanoid.Health <= 1 then
								if dead == false then
									script["arsenal kill sound"]:Play()
									script["Kill sound"]:Play()	
									kills.Value = kills.Value + 1
									dead = true
								end
							end
						end
					end
				end
			end
		end
	end)
end

Here is the local script that reloads the gun

local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")
local equip = false

	equip = true

	uis.InputBegan:Connect(function(hit)
	if hit.KeyCode == Enum.KeyCode.R then
		script.Parent.Chamber.Value = 9
		print("reloaded")
		script.r:Play()
	end 
	end)

The Explorer of the gun

Any help would be great and I would be really thankful. Anyways have a good day internet.

2 Likes

I’m pretty sure why it doesn’t work, is because you set the ammo back to 9 in a local script. As you may know server-sided scripts dont detect client sided changes so you’ll have to do it this way:

Client-Side:

local RemoteEvent = script.Parent:WaitForChild("ReloadEvent")
local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")
local equip = false

script.Parent.Equipped:Connect(function() 
	equip = true
end)
script.Parent.Unequipped:Connect(function() 
	equip = false
end)
local Reloading = false
uis.InputBegan:Connect(function(hit)
	if hit.KeyCode == Enum.KeyCode.R then
		if equip and not Reloading then
			Reloading = true
			task.spawn(function()
				task.wait() -- if you want the reload to be instant then leave it 
				Reloading = false
			end)
			script:WaitForChild("r", 0.05):Play()
			RemoteEvent:FireServer("Reloading")
		end
	end 
end)

ServerSide:

local ReloadEvent = script.Parent.ReloadEvent
local ReloadDebounce = false
local ChamberValue = script.Parent.Chamber
ReloadEvent.OnServerEvent:Connect(function(player, ting)
	if ting == "Reloading" then
		if ReloadDebounce == false then
			if ChamberValue.Value < 9 then
			ReloadDebounce = true
			task.spawn(function()
				task.wait() -- if reload is instant leave it
				ReloadDebounce = false
			end)
				ChamberValue.Value = 9
			end	
		end
	end
end)
3 Likes

Thanks for the idea but for some reason it does not work. I have added print scripts but it does not work maybe its a simple scripting error but I have looked at it and I can’t seem to understand how it doesn’t work. Thank you though

1 Like

The local script seems to work however the script does not seem to receive the remote event

1 Like

i did a little mistake on the server script it cant be (ting) it needs to be (player, ting) so fix that

4 Likes

Yo thank you! it works really well have a nice day :slight_smile:

1 Like

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