CollectionService KillBrick problem

I am using the Collection Service to make parts with a certain tag kill people. It works perfectly but when i create a new part and give it the tag touching the newly spawned in part does nothing, what am i doing wrong?

local CollectionService = game:GetService("CollectionService")
local KillBricks = CollectionService:GetTagged("KillBricks")

local Part = Instance.new("Part",game.Workspace)
Part.Name = "KillBrick"
CollectionService:AddTag(Part,"KillBricks")

CollectionService:GetInstanceAddedSignal("KillBricks"):Connect(function()
	for i,KillBrick in pairs(KillBricks) do
		KillBrick.Touched:Connect(function(hit)
			local humanoid = hit.Parent:FindFirstChild("Humanoid")
			if humanoid then
				humanoid.Health = 0
			end
		end)
	end
end)	
2 Likes

You only get the list of your killbricks at the beginning of your script.
The table does not automatically update, you have to run GetTagged again when new parts are added.

This code runs once when the server starts meaning anything added during runtime won’t be check. You can use workspace.DescendantAdded to run the check on that newly added instance

For starters, it’s unnecessary to cache your parts. CollectionService passes a newly tagged object as an argument to your connected function, so you should treat each part independently. Right now your script is going to duplicate connections very badly.

local CollectionService = game:GetService("CollectionService")

local function onNewKillBrick(part)
    if not part:IsA("BasePart") then return end -- Early out if not a part

    -- A print just to show that it works
    print("Registering a new kill brick")

    part.Touched:Connect(function (hit)
        -- Put your kill code here
    end)
end

-- Doing it this way is important to prepare for Deferred SignalBehavior
-- eventually becoming the default for Roblox events.
CollectionService:GetInstanceAddedSignal("KillBrick"):Connect(onNewKillBrick)
-- Here we'll apply it to existing ones.
for _, killBrick in CollectionService:GetTagged("KillBrick") do
    onNewKillBrick(killBrick)
end

-- And here, we can add a new one for testing. Remember to not use the
-- parent argument of Instance.new.
local part = Instance.new("Part")
part.Name = "KillBrick"
part.Parent = workspace
-- There are instance-level tagging methods you can use.
part:AddTag("KillBrick")

Your current code by design will only repeatedly connect to Touched for parts that exist before you establish the connection, though it does have another issue as well which is that you’re unnecessarily performing an iteration across existing tagged parts in your connection which you shouldn’t. Treat each new part independently.

1 Like

Instead of using tags and CollectionService, you could put all the kill bricks into a folder and insert a script. Name it KillBrickHandler.
The hierarchy should look like this:
image
Insert this code into your script:

local folder = script.Parent

for _, part in pairs(folder:GetChildren()) do
	if part:IsA("Part") then
		part.Touched:Connect(function(otherPart)
			local Character = otherPart.Parent
			local Humanoid = Character:FindFirstChild("Humanoid")
			
			if Humanoid then
				Humanoid:TakeDamage(Humanoid.MaxHealth)
			end
		end)
	end
end

Hope this helps! :slight_smile:

2 Likes

You can do this, but that will lock the Parts to the folder, whereas the CollectionService solution would allow you to parent the Parts anywhere

3 Likes

What if all parts are parented under one instance? Will that differ from using collectionservice?

If the parts are already under one parent, then the iteration solution would suffice over CollectionService

1 Like

You could try moving the per-killbrick logic (the Touched connection) to its own function (I’ll call it setup(part) here), looping through all of the killbricks found with :GetTagged() once and calling setup(part) on each of them, and then connecting the InstanceAddedSignal to setup

So:

local CollectionService = game:GetService("CollectionService")

-- Define a setup function to reduce code duplication
local function setupKillbrick(part)
    part.Touched:Connect(function()
        -- Your logic goes here
    end)
end

-- Loop through all of the killbricks that already exist when the script loads and set them up
for _,part in CollectionService:GetTagged("KillBricks") do
    setupKillbrick(part)
end

-- Listen for newly created killbricks and set them up
CollectionService:GetInstanceAddedSignal("KillBricks"):Connect(setupKillbrick)
-- The instance added event provides the newly added instance as the first argument, so we can connect it directly to the setup function

Also note is that you can use simplyh table of parts, you don’t need to use collection service every time