Confused about collectionservice

I’m not really familiar with collectionservice, but I wanna make all ammo controlled by one script but it’s currently not working. I watched GnomeCode’s video on it, and I tried basing it off his code, but it doesn’t work, and I don’t understand why.

local CollectionService = game:GetService("CollectionService")

local function Enabler(lightammo,Player)
	
	local Ammo = math.huge --Amount of Ammo to give. Set it to "math.huge" to refill the gun's ammo.
	local GunToRefillAmmo = {
		"M9",
		"M9-S",
		"Ruger 22",
		"Full-Auto Ruger 22",
		"MAC-10",
		--Add more gun here if you want
	}
	
	local Enabled = true
	if Enabled and Player then
		local AmmoRefilled = false
		for _, GunName in pairs(GunToRefillAmmo) do
			local Gun = Player.Backpack:FindFirstChild(GunName) or Player.Character:FindFirstChild(GunName)
			if Gun then
				local GunScript = Gun:FindFirstChild("GunScript_Server")
				local Module = Gun:FindFirstChild("Setting")
				if GunScript and Module then
					local Module = require(Module)
					if GunScript.Ammo.Value < Module.MaxAmmo and Module.LimitedAmmoEnabled then
						Enabled = false
						AmmoRefilled = true
						local ChangedAmmo = (Ammo == math.huge or GunScript.Ammo.Value + Ammo >= Module.Ammo) and Module.MaxAmmo or (GunScript.Ammo.Value + Ammo)
						GunScript.Ammo.Value = ChangedAmmo
						GunScript.ChangeMagAndAmmo:FireClient(Player,Module.AmmoPerMag,ChangedAmmo,0)
					end
				end
			end
		end
		if AmmoRefilled then lightammo:Destroy() end
	end
end

for i, lightammo in pairs(CollectionService:GetTagged("LightAmmo")) do
	local Click = lightammo.ClickDetector
	
	--Click.MouseClick:Connect(lightammo, Enabler)
	Click.MouseClick:Connect(function()
		Enabler(lightammo)
	end)

	task.wait(120)
	lightammo:Destroy()
end

Read CollectionService:GetInstanceAddedSignal

Basically put the code in the for loop body into a function so that you can both connect it to the instance added signal and run it in the for loop.

I’m confused on how to do that

Did you look at the code sample underneath the description of GetInstanceAddedSignal?

Yeah, its still somewhat confusing for me

CollectionService:GetInstanceAddedSignal("LightAmmo"):Connect(function(lightammo)
    local Click = lightammo.ClickDetector
	
	--Click.MouseClick:Connect(lightammo, Enabler)
	Click.MouseClick:Connect(function()
		Enabler(lightammo)
	end)

	task.wait(120)
	lightammo:Destroy()
end)

the reason you wanna do this is because with your current code its only getting ammo that exists when the script runs. This listens for new ones

1 Like

Basically my intuition tells me the problem is that your code is not running because the script will run before any tagged instances are created.
That means that you need to somehow process the newly tagged objects at any point in the game.

SIDE NOTE
Also I just noticed you have a 120 second yield in your for loop, which wouldn’t make sense to do like that. The best solution in your case is to use Debris, but the general solution for later-use code is to use task.delay.
For timing you can use a lot of the task functions.

To rearrange your code I would do this so far:

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

local function Enabler(lightammo,Player)
	
	local Ammo = math.huge --Amount of Ammo to give. Set it to "math.huge" to refill the gun's ammo.
	local GunToRefillAmmo = {
		"M9",
		"M9-S",
		"Ruger 22",
		"Full-Auto Ruger 22",
		"MAC-10",
		--Add more gun here if you want
	}
	
	local Enabled = true
	if Enabled and Player then
		local AmmoRefilled = false
		for _, GunName in pairs(GunToRefillAmmo) do
			local Gun = Player.Backpack:FindFirstChild(GunName) or Player.Character:FindFirstChild(GunName)
			if Gun then
				local GunScript = Gun:FindFirstChild("GunScript_Server")
				local Module = Gun:FindFirstChild("Setting")
				if GunScript and Module then
					local Module = require(Module)
					if GunScript.Ammo.Value < Module.MaxAmmo and Module.LimitedAmmoEnabled then
						Enabled = false
						AmmoRefilled = true
						local ChangedAmmo = (Ammo == math.huge or GunScript.Ammo.Value + Ammo >= Module.Ammo) and Module.MaxAmmo or (GunScript.Ammo.Value + Ammo)
						GunScript.Ammo.Value = ChangedAmmo
						GunScript.ChangeMagAndAmmo:FireClient(Player,Module.AmmoPerMag,ChangedAmmo,0)
					end
				end
			end
		end
		if AmmoRefilled then lightammo:Destroy() end
	end
end

local function handle(lightammo)
	local Click = lightammo.ClickDetector
	
	--Click.MouseClick:Connect(lightammo, Enabler)
	Click.MouseClick:Connect(function()
		Enabler(lightammo)
	end)

	Debris:AddItem(lightammo, 120)
end

CollectionService:GetInstanceAddedSignal("LightAmmo"):Connect(handle)
for i, lightammo in pairs(CollectionService:GetTagged("LightAmmo")) do
	task.spawn(handle, lightammo)
end

I’m using the tag editor plugin btw, and also the 120 second yield is because I want the ammo box to disappear after a certain time, and the script also doesn’t work for me.

@Voidage your script also doesn’t work for me, even new ammo boxes don’t work

you should really learn to script before, well… trying to script? like we’ve provided you with the documentation for collectionservice. how are you gonna use collectionservice if you don’t even understand the basics? it’s not very hard to use. I use it all the time without problem. as far as I can tell my code is correct and the other person who replied is as well, you probably implemented it incorrectly or things are going wrong elsewhere.
sorry if this sounds rude but having others fix and make code for you on the devforums when you run into a problem is not a good way to script stuff

2 Likes

Solved by doing the dumbest fix ever

1 Like