Collection Service in LocalScript

So I use a collection service to make a script , where player clicks on the part and cframe of part changes to players left hand and welds.

Everything works fine but when I put script into a local script , GetTagged() function just cant detect parts

local CollectionService = game:GetService("CollectionService")

local CurrentIngredient = nil

for i, Ingredient in pairs(CollectionService:GetTagged("CollectIngr")) do
	Ingredient:WaitForChild("ClickDetector").MouseClick:Connect(function(plr)
		local Char = workspace:FindFirstChild(plr.Name)
		local LeftArm = Char:WaitForChild("Left Arm")
		local PlrCurIngredient = plr:FindFirstChild("HoldingIngr")

		if not CurrentIngredient then
			PlrCurIngredient.Value = Ingredient.Name
			CurrentIngredient = Ingredient
			print(CurrentIngredient)


			Ingredient.CanCollide = false
			Ingredient.CFrame = LeftArm.CFrame * CFrame.new(0,-1,0)

			weld = Instance.new("WeldConstraint")
			weld.Name = "IngrWeld"
			weld.Part0 = Ingredient
			weld.Part1 = LeftArm
			weld.Parent = LeftArm

			Ingredient.Parent = LeftArm

		end

	end)
end

for i , Prompt in pairs(CollectionService:GetTagged("CauldronPrompt")) do
	Prompt.Triggered:Connect(function(plr)
		local Cauldrons = CollectionService:GetTagged("Cauldron")
		
		local Char = workspace:FindFirstChild(plr.Name)
		local LeftArm = Char:WaitForChild("Left Arm")
		local PlrCurIngredient = plr:FindFirstChild("HoldingIngr")

		local module = require(script.ModuleScript)

		if PlrCurIngredient.Value ~= "" then
			for i , Cauldron in ipairs(Cauldrons) do
				local Billboard = Cauldron:FindFirstChild("Ingredients")
				local Order = #Billboard:GetChildren()

				if Order < 3 then
					module.NewTextLabel(Billboard , Order , PlrCurIngredient)


					if LeftArm:FindFirstChild("IngrWeld") then
						LeftArm:FindFirstChild("IngrWeld"):Destroy()
					end

					for i , Ingredient in pairs(CollectionService:GetTagged("CollectIngr")) do
						if LeftArm:FindFirstChild(Ingredient.Name) then
							LeftArm:FindFirstChild(Ingredient.Name):Destroy()
							CurrentIngredient = nil
						end
					end
				end

			end
		end
	end)
end
1 Like

My first guess is the WaitForChild event isn’t firing because the clickdetector has already been added, causing it to hang.
Inside the loop try using the pattern:

local cd = Ingredient :FindFirstChild("clickdetector") or WaitForChild("clickdetector", 1)
if not cd then print("missing clickdetector") continue end
cd.MouseClick --connect event etc
2 Likes

The issue you’re experiencing is because Instances take time to finish loading for LocalScripts. Luckily, CollectionService is able to detect when a tagged Instance finishes loading using the GetInstanceAddedSignal method, but we’ll still need to use GetTagged to fetch the Instances that were successfully loaded. Here’s what you’ll need to do to fix the problem:

local CollectionService = game:GetService("CollectionService")

local CurrentIngredient = nil

local function CollectIngr(Ingredient)
	Ingredient:WaitForChild("ClickDetector").MouseClick:Connect(function(plr)
		local Char = workspace:FindFirstChild(plr.Name)
		local LeftArm = Char:WaitForChild("Left Arm")
		local PlrCurIngredient = plr:FindFirstChild("HoldingIngr")

		if not CurrentIngredient then
			PlrCurIngredient.Value = Ingredient.Name
			CurrentIngredient = Ingredient
			print(CurrentIngredient)


			Ingredient.CanCollide = false
			Ingredient.CFrame = LeftArm.CFrame * CFrame.new(0,-1,0)

			weld = Instance.new("WeldConstraint")
			weld.Name = "IngrWeld"
			weld.Part0 = Ingredient
			weld.Part1 = LeftArm
			weld.Parent = LeftArm

			Ingredient.Parent = LeftArm

		end

	end)
end

local function CauldronPrompt(Prompt)
	Prompt.Triggered:Connect(function(plr)
		local Cauldrons = CollectionService:GetTagged("Cauldron")

		local Char = workspace:FindFirstChild(plr.Name)
		local LeftArm = Char:WaitForChild("Left Arm")
		local PlrCurIngredient = plr:FindFirstChild("HoldingIngr")

		local module = require(script.ModuleScript)

		if PlrCurIngredient.Value ~= "" then
			for i , Cauldron in ipairs(Cauldrons) do
				local Billboard = Cauldron:FindFirstChild("Ingredients")
				local Order = #Billboard:GetChildren()

				if Order < 3 then
					module.NewTextLabel(Billboard , Order , PlrCurIngredient)


					if LeftArm:FindFirstChild("IngrWeld") then
						LeftArm:FindFirstChild("IngrWeld"):Destroy()
					end

					for i , Ingredient in pairs(CollectionService:GetTagged("CollectIngr")) do
						if LeftArm:FindFirstChild(Ingredient.Name) then
							LeftArm:FindFirstChild(Ingredient.Name):Destroy()
							CurrentIngredient = nil
						end
					end
				end

			end
		end
	end)
end

task.spawn(function()
	CollectionService:GetInstanceAddedSignal("CollectIngr"):Connect(CollectIngr)

-- Do note that there's no longer a need to use pairs or ipairs in Luau
	for i, Ingredient in CollectionService:GetTagged("CollectIngr") do CollectIngr(Ingredient) end
end)

task.spawn(function()
	CollectionService:GetInstanceAddedSignal("CauldronPrompt"):Connect(CauldronPrompt)

	for i, Prompt in CollectionService:GetTagged("CauldronPrompt") do CauldronPrompt(Prompt) end
end)
2 Likes

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