- Home /
How To Get List of Child Game Objects
Sometimes a game object has child game objects. Likewise, a game object can have a parent. In the past I tried getting all child game objects by using this:
List gs = new List();
Transform[] ts = gameObject.GetComponentsInChildren<Transform>();
if (ts == null)
return gs;
foreach (Transform t in ts) {
if (t != null && t.gameobject != null)
gs.Add(t.gameobject);
}
return gs;
But I have recently proven this is unreliable when running from the editor. I have loaded in from a collada file the main game object. In the hierarchy view, I see the game object with all of its children. However, my script returns an empty list.
Can somebody please tell me a reliable way to get child objects?
Can somebody please tell me a reliable way to get the parent game object?
Basically what I did was AssetDatabase.Load$$anonymous$$ainAssetAtPath, and followed it up with GameObject.Instantiate. With the instance it creates, I see in the hierarchy view there are children game objects. Still, the script returns an empty list.
A clever recursive function to obtain all the children of a game object down multiple levels of hierarchy! https://github.com/aniketrajnish/get-all-children-of-a-gameobject/blob/main/ChildList.cs
Answer by Julien-Lynge · Jan 13, 2012 at 10:36 PM
The suggestions I've seen from smart people like Eric5h5 is to use the build-in transform functions, rather than GameObject.Find. Since it looks like you're using C#, the following is also in C#:
To get children:
foreach (Transform child in transform)
{
//child is your child transform
}
To get parent:
transform.parent;
why on earth cannot unity just build this capability into their API? ridicolous.
The issue as stated before is that this returns the Transform of "transform" in the foreach loop, adding: if (child != transform[0]){} will eli$$anonymous$$ate the transform you're wanting to get children from.
which would change the code to:
foreach (Transform child in transform)
{
if (child != transform[0]){
//child is your child transform
}
}
@DCrosby I just checked and that does not seem to be the case. Iteration over the transform does not include itself.
I don't like this solution since it finds the child's transform and not the child itself. $$anonymous$$aybe I'm missing something...
Just in case you didn't figure it out after 4 years, honestly not busting your chops at all, transform.gameObject will be that transforms actual game object. Generally when working in Unity, the transform contains most of the same properties and points to the same Components as they both inherit the Object class.
$$anonymous$$y solution was similar but here is the full code, and you can get to the game object itself from it:
Transform[] allChildren = GetComponentsInChildren<Transform>();
foreach (Transform child in allChildren)
{
child.gameObject.SetActive(false);
}
So as you can see it's easy to get to the gameObject.
You just spam the same comment on all questions that have anything to do with finding child objects. This comment makes no sense as you posted exactly the same code the OP used in his question.
Please stop bumping three years old, answered question for no reason.
Answer by pprofitt · Jun 07, 2014 at 02:40 PM
public List<GameObject> Children;
foreach (Transform child in transform)
{
if (child.tag == "Tag")
{
Children.Add(child.gameObject);
}
}
In c# you can use this code to get all the child objects with a certain tag.
I use this method. Even if your not filtering by tag, storing the children in a List is the only way to use methods like: System.Array.Reverse(Children)
because Transform doesn't have a built-in GetEnumerator.
Your first line of code is incorrect. When declaring the Children list there is no need to add public
in front of it. Children is a local variable, not a property. It will be available to the foreach loop anyway, because they are both on the same function scope. Also, you are not instantiating the list, which some IDEs (such as Visual Studio) will report as an error. In short, you should fix the first line to: List<GameObject> Children = new List<GameObject>();
Should Children not also be lowercase to follow convention?
Follow unitys but not follow nearly all of c# conventions. Including that of the .NET framework.
So no it is wrong and Unity should feel bad about it. :)
Answer by Pix10 · Jan 19, 2013 at 07:00 PM
foreach(Transform child in transform) is unreliable, as is GetComponentsInChildren, as they won't traverse the entire tree of children.
This will correctly return all the children:
void Start () {
Debug.Log("Child Objects: " + CountChildren(transform));
}
int CountChildren(Transform a)
{
int childCount = 0;
foreach (Transform b in a)
{
Debug.Log("Child: "+b);
childCount ++;
childCount += CountChildren(b);
}
return childCount;
}
No it won't, you're script returns the number of children not a list of them. Besides you can just use transform.childCount to get the number of children anyway.
As far as I know, "children" refers to the transforms on the next level only, while "descendants" would refer to every transform below this one in the tree. If the goal was to iterate over all descendants, the code example shows a way to do that recursively.
This is generically wrong, GetComponentsInChildren does transverse the entire tree of children, not just the immediate children. It might not behave correctly when used with Transform's though.
Answer by jason891107 · Oct 26, 2012 at 04:02 AM
foreach (Transform child in transform) { //child is your child transform } This is right.
GetComponentsInChildren will get gameObject's transform as well.
Answer by Dinkelborg · Jan 13, 2014 at 10:50 PM
The best Answer would be a recursive function I guess ...
So the function will go and look at the first Transform it finds in transform then it will do whatever you want to do (add it to a list or array or whatever) in this case it will change the active and passive colour stored in a level element... after it has done what it should it will see if the object has any children.
"!" Although this works sometimes there seems to be a real problem with the childCount function in about 50 percent of all objects it does not see the last layer of the hierarchy.
"!!" There is also one problem with this: If you add new layers OnStart of the Game and you also execute the script at the same time as these will get created it might not see them... -?- Is there any way to time this or should I just use a yield WaitForSeconds in the start function...?
public void Start ()
{
StartCoroutine(OverrideAllChildren(transform));
}
public IEnumerator OverrideAllChildren(Transform pTransform)
{
foreach(Transform child in pTransform)
{
TouchQube temp = child.GetComponent<TouchQube>();
if(temp != null)//If it is a TouchQube
{
totalCount++;
if(overrideInactive){temp.SetInactiveLight(overrideColor);}
if(overrideActive){temp.SetActiveLight(overrideColor2);}
}
Debug.Log(child.name+" has "+CountChildren(child)+" children. TotalOverwritten: "+totalCount);
if(HasChildren(child))//If it has children
{
StartCoroutine(OverrideAllChildren(child));
}
}
yield return(true);
}
public bool HasChildren(Transform pTransform)
{
int count = 0;
foreach(Transform child in pTransform)
{
count++;
}
if(count > 0){return true;}else{return false;}
}
public int CountChildren(Transform pTransform)
{
int count = 0;
foreach(Transform child in pTransform)
{
count++;
}
return count;
}
Your answer
Follow this Question
Related Questions
Make a simple tree 1 Answer
Change an object's grandparent 2 Answers
Child cant apply variables from parent 2 Answers
How to move the parent object to a child of one of its children? 2 Answers
Set up rank children 1 Answer