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.
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.
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.
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.
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.
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.
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.
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.