Get workspace descendants while more parts are being added

Hi. I’m spawning 1 part per second, but I noticed that with this script, GetDescendants does not take into account the new parts I am spawning into the game each second (only the ones that were there when the server started). See below

for i,v in pairs(workspace:GetDescendants()) do
		if v.Name == "Part" then
			v.Touched:Connect(function(hit)
				if hit.Parent:FindFirstChild("Humanoid") then
					local player = game.Players:GetPlayerFromCharacter(hit.Parent)
					if player then
						v:Destroy()
					end
				end
			end)
		end
	end

I was able to fix it (see below) using a constant wait(), but is there a more efficient way?

while wait() do  -- new code
	for i,v in pairs(workspace:GetDescendants()) do
		if v.Name == "Part" then
			v.Touched:Connect(function(hit)
				if hit.Parent:FindFirstChild("Humanoid") then
					local player = game.Players:GetPlayerFromCharacter(hit.Parent)
					if player then
						v:Destroy()
					end
				end
			end)
		end
	end
end -- new code

The goal is parts spawn in the world, and the player has to step on them to destroy them, however parts that are added are not being used in the GetDescendants. Please help

– The alternative I guess is to put a script in every part, but is that efficient? will it be laggy?

There’s an event you can use for the workspace called .DescendantAdded, which will fire each time a descendant is added to the workspace, and it returns the descendant as a parameter to be used in functions.

It would look similar to this:

local function onPartAdded(part)
    if part.Name == "Part" then
        part.Touched:Connect(function(hit)
            if hit.Parent:FindFirstChildWhichIsA("Humanoid") then
                local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	            if player then
		        part:Destroy()
		    end
        end     
    end
end

for i, v in pairs(workspace:GetDescendants()) do
		onPartAdded(v)
end

workspace.DescendantAdded:Connect(onPartAdded)

https://developer.roblox.com/en-us/api-reference/event/Instance/DescendantAdded

2 Likes
local players = game:GetService("Players")

local function onPartTouched(part, hit)
	local hitModel = hit:FindFirstAncestorOfClass("Model")
	if hitModel then
		local hitPlayer = players:GetPlayerFromCharacter(hitModel)
		if hitPlayer then
			part:Destroy()
		end
	end
end

local function onDescendantAdded(descendant)
	if descendant:IsA("BasePart") then
		descendant.Touched:Connect(function(hit)
			onPartTouched(descendant, hit)
		end)
	end
end

for _, descendant in ipairs(workspace:GetDescendants()) do
	onDescendantAdded(descendant)
end

workspace.DescendantAdded:Connect(onDescendantAdded)
1 Like