Add Instance:GetDescendants()

As a Roblox developer, it is currently too hard to get all the descendants of an object. Currently, the best solution is to write a recursive function to get all the descendants. Because myself (and I’m sure others) utilize this process of getting all descendants, it would be nice if there was a single method to do it.

One could argue that recursive functions are a bit of a learning curve for those new to scripting. Also, it feels like I’m writing these recursive functions very frequently.

While some could argue that this could be a good utilization of ModuleScripts, I would argue that such a feature makes a lot of sense to exist within the actual API due to its relevancy to how developers use objects within the hierarchy all the time.


Here’s the way some developers will get all descendants currently. I know some do it slightly differently:

function GetDescendants(object)

	local descendants = {}

	local function Scan(parent)
		for _,v in pairs(parent:GetChildren()) do
			table.insert(descendants, v)
			Scan(v)
		end
	end

	Scan(object)

	return descendants
	
end

Here’s what I would propose:

local descendants = object:GetDescendants()

I’m sure some would also find it beneficial to have filters added to such a method (e.g. only get descendants of a certain class). But I guess that’s another topic of its own.

Let me know what you guys think.

32 Likes

It looks like this API has already been approved to add, but the person who was going to implement it isn’t working here anymore. I will pick it up and try to get it shipped.

75 Likes

Oh, that’s awesome. Thanks!

1 Like

Great to hear. Thanks so much!

Finally :smiley:
Thank you!

Very appreciated. This will definitely be a big time saver! :smiley:

its happening
spotted on gametest2
:

10 Likes

Do you know if there’s any significance to GetDescendants returning an Array and GetChildren returning Objects?

In practice from Lua, not really. The return type is dependent upon how they choose to implement it in C++, and how Roblox’s reflection system interprets it.

The difference between Objects and Array is that Objects can only store Instances, whereas Arrays are able to store any Variant, including Instances.

cc @Tiffblocks

1 Like

Another thing to note is that on the wiki, you won’t see this distinction.
We have a type system setup so that we can override types for parameters, return types, and value types, so that we can further elaborate on the functionality of Roblox’s API.

Objects is automatically converted to array<Instance> and Array is convert to array<Variant> until we specify what the Variant is.

Example

With type override:

Without type override:

1 Like

Well that was fast

1 Like

The way I implemented GetDescendants means that the return type is purely visual/documentation. It uses raw Lua API manipulation to create the table and put the instances in it (like Terrain:ReadVoxels()). Both Array and Objects correspond to different types internally, when not using raw Lua API.

2 Likes

Noticed that this was added today. Awesome! Excited for it to be enabled.

1 Like

Instance:GetDescendants() is now enabled. However, as of right now only desktop, studio, and iOS are on new enough versions to support it.

7 Likes

Thanks for this amazing feature, saves alot of time, would it be possible to add an argument to GetDescendants for class, so you can do Instance:GetDescendants(“BasePart”) to return all BaseParts within that instance, would save even more time by not having to loop through GetDescendants and create a new table.

1 Like

GetDescendantsOfClass, perfect.

2 Likes

The api is going to get so messy! We just need a single powerful method like :GetDescendantsOfCondition(condition), where condition would be much more generic.

You could also potentially use that suggested feature to filter parts where CanCollide=false, or Transparency=1, or any combination of things, and most importantly it would be fast.

10 Likes

I love this idea, full support

2 Likes

I’ve considered adding GetDescendantsOfClass and GetDescendantsWhichAre methods to accompany it. It seems relevant to the common usecase of model-based invisicam, because recursing through the model and calling :IsA() on everything to find stuff to make transparent is quite slow.

5 Likes

What do you think of @Tomarty’s post a couple up?

1 Like