Finding all Humanoids takes too much more time than expected

I am trying to make a radar tool that outlines players. However, it will be like LIDAR, where you have to scan again for the outlines to update.
The way it works is:

  1. Loop through all parts and find humanoids
  2. Add all humanoid/characters into a table
  3. Loop through table and clone the Outline into each character’s torso
  4. Adjust position accordingly
  5. Add all clonedOutlines into another table
  6. Destroy all clonedOutlines after a delay.

The clonedOutline has a Highlight in it, so the Radar works through walls.
Everything is working as intended, however the time it takes to loop through the parts takes longer than expected (5-6 seconds with 3 humanoid characters)

A video of the behavior is here:

The code used:

local tool = script.Parent

tool.Activated:Connect(function()
	local Characters = {}
	for i,v in pairs (game:GetService("Workspace"):GetDescendants()) do
		task.wait()
		if v:FindFirstChild("Humanoid") ~= nil and v.Name ~= script.Parent.Parent.Name then
			local Char = table.find(Characters,v,1)
			if Char == nil then
				table.insert(Characters,v)
			end
		end
	end
	
	local cloneTable = {}
	for i,v in pairs(Characters) do
		local clonePart = script.Outline:Clone()
		clonePart.Parent = v.Torso
		clonePart.Position = v.Torso.Position
		clonePart.Transparency = 0.75
		
		table.insert(cloneTable, clonePart)
	end
	
	wait(5)
	for i,v in pairs(cloneTable) do
		v:Destroy()
	end
end)

Thanks in advance!

if i’m understanding right you could just use collectionservice to tag a humanoid on spawn and then use
CollectionService | Documentation - Roblox Creator Hub ( this links to CollectionService:GetTagged() ) instead of searching all descendants of the workspace

also use task.wait over wait

1 Like

I’ve noticed a few issues that can make your code slow:
1 - Looping through all descendants in workspace
2 - Using FindFirstChild, task.wait, table.find inside the for loop

I have a few suggestions:
Use CollectionService to tag all players or NPCs characters you want, then instead of looping through each descendant in workspace, just loop through the Characters table and apply the desired effect.

Here’s a example on how it would look

local CollectionService = game:GetService("CollectionService")

local Characters = {} -- Here is where we will store the models

local CHARACTERS_TAG = "Characters" -- Here you will set your characters tag

local function characterAdded(character)
	if not table.find(Characters, character) then
		table.insert(Characters, character)
	end
	table.insert(Characters, character)
end

local function characterRemoved(character)
	local index = table.find(Characters, character)
	if index then
		table.remove(Characters, index)
	end
end

for _, character in CollectionService:GetTagged(CHARACTERS_TAG) do -- we do this loop to register the existing characters
	characterAdded(character)
end

--listen to new changes
CollectionService:GetInstanceAddedSignal(CHARACTERS_TAG, characterAdded)
CollectionService:GetInstanceRemovedSignal(CHARACTERS_TAG, characterRemoved)

After this, you can just use the tool.Activated event and do the loop through the Characters table

local function toolActivated()
	for _, character in Characters do
		-- do the logic here
	end
end

tool.Activated:Connect(toolActivated)

I’ll attach this place file (92.4 KB) so you can check how it works

Thank you for your detailed response, but I don’t think that it could work in my case.
The radar tool I am making is supposed to be plug and play, so it works in any game, no need for any setup.

But, I think this response could help a lot of people, thank you!

Also, in my case, removing task.wait() in the first for loop corrected the behavior.

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