Collectionservice only works with one instance per tag

I’ve rewritten the same piece of code at least 4 times now and i keep having the same problem every single time.


I’m trying to use collectionservice for all the elements of my puzzle game so i can run the same code for every door, button etc. However, whatever I do, if there are two instances with the same tag only one of them will function. Every time I rewrite this. I’ve looked up this service several times now and I always get the same result.

I don’t know what I’m doing wrong. From every tutorial I’ve read, I’m not doing anything wrong anyway.

Here is my latest attempt which doesn’t work:

local CollectionService = game:GetService("CollectionService")

local tags = {door = 'door_exit'}

local function setDoorState(door, state)
	for _, b in pairs(door.Positions:GetChildren()) do
		if b:IsA('BasePart') then b.Transparency = 1 end
	end
	
	door.Components.Collision.Transparency = 1
	
	for _, part in pairs(door.Lights:GetChildren()) do
		if part:IsA('BasePart') then
			part.Color = (state and Color3.fromRGB(91, 154, 76) or Color3.fromRGB(255, 55, 55))
		end
	end
	
	game.ReplicatedStorage.Animate.AnimateChamberDoor:FireAllClients(door, state, door.Configuration.OpeningTime.Value)
	door.Components.Collision.CanCollide = not state
end

function doorHandling(door)
	spawn(function()
			
			running = true
			config = door.Configuration
			state = false
			
			if config.Requirement.Value then
				spawn(function()
				while door and running do
					wait()
					if door and config.Requirement.Value then
						enabled = config.Requirement.Value.Configuration.Enabled.Value
						if state ~= enabled then
							state = enabled
							setDoorState(door, state)
						end
					else
						break
					end
				end
				end)
			else
				spawn(function()
					while running and door do
						wait()
						local open = false
						for _, plr in pairs(game.Players:GetPlayers()) do
							local character = plr.Character
							if character and character.Humanoid.Health > 0 then
								local distance = (door.Positions.CentralPoint.Position - character.HumanoidRootPart.Position).magnitude
								if distance <= config.MinimumDistance.Value then
									open = true
									break
								end
							end
						end
						if state ~= open then
							state = open
							setDoorState(door, state)
						end
					end
				end)
			end			
		end)
		
end

local function updateTaggedObjects()
	
	local taggedParts = CollectionService:GetTagged('door_exit')
	
	for _, door in pairs(taggedParts) do
		doorHandling(door)
	end
	
end

updateTaggedObjects()

What I’m trying to do is have a door that has a config folder that allows me to adjust things such as the speed the door opens, the minimum distance a player needs to be to open automatically and whether or not the door requires a trigger e.g. a button to be enabled to be able to open.

The RemoteEvent is just for client side animations. It doesn’t change anything else.

It works, but only for one door, one button etc. Whenever there is more than one object with the same tag as another one, it will be ignored for some reason. Only one object per tag will function.

Here is my door layout:

door

Can someone with better knowledge of CollectionService and OOP style programming PLEASE help me out here, I’m getting frustrated with this and it’s hindering my entire game development.

It’s probably because because of these global variables:

running = true
config = door.Configuration
state = false

I would suggest changing these to local:

local running = true
local config = door.Configuration
local state = false

This is just a little nitpick on

SPAWN

A really big nitpick actually

spawn sometimes takes many seconds to execute, although spawn is simple to use, using coroutines can be so much better. Not only is it better, it is also more versatile. So instead of doing this:

spawn(function()
    -- code
end)

Use this:

coroutine.wrap(function()
    -- code
end)() -- Don't forget these last 2 brackets

Okay, thanks for that. I’ll try switching out those for local variables.

Also I was using spawn because I had written this many times and was just trying to get something that worked, then I’d sort out efficiency and all the other stuff

It worked! Thank you so much! I was really stressing over this because it was such a crucial aspect of my game. Can’t believe those stupid global variables messed p the whole thing :happy3:

And also, thanks for pointing out the spawn() and coroutine stuff, I’ll switch over to coroutine now :slight_smile:

1 Like

From research(mostly because I got corrected), I found out that spawn was okay to use, but you just have to limit using it. coroutine is more or less good practice.