I need a way to retrieve the immediate children of any given gameobject, but not grandchildren. Transform.childCount does not include grandchildren, yet there is no easy way to access a collection with the children it counts.
For example:
parent
child1
grandchild1
child2
grandchild2
Accessing transform.childCount on parent returns 2, but the way I’ve been using to get its children returns all 4 of its descendants.
This is what I’ve been doing, but there must be a better way:
Transform[] children = transform.GetComponentsInChildren<Transform>();
foreach (Transform child in children)
{
if (child.parent == transform)
child.GetComponent<SomeComponent>().DoSomething();
}
It seems like an omission that you can very easily access the parent but not the children!
Thank you! I looked in that page many times but I scrolled right past that code every time because I was expecting it to be in some variable called Transform[ ] children. I didn’t notice that Transform was IEnumerable so you can just use a foreach loop on it. Kind of unintuitive, but what are you gonna do.
Not to revive this thread but for any individuals looking I just wrote this method to get the components only of direct children. It isn’t 100% efficient and could be improved on but here ya go:
public static T[] GetComponentsInDirectChildren<T>(GameObject gameObject)
{
int indexer = 0;
foreach (Transform transform in gameObject.transform)
{
if (transform.GetComponent<T>() != null)
{
indexer++;
}
}
T[] returnArray = new T[indexer];
indexer = 0;
foreach (Transform transform in gameObject.transform)
{
if (transform.GetComponent<T>() != null)
{
returnArray[indexer++] = transform.GetComponent<T>();
}
}
return returnArray;
}
using System.Collections.Generic;
namespace UnityEngine
{
public static class UnityEngineEx
{
public static T GetComponentInDirectChildren<T>(this Component parent) where T : Component
{
return parent.GetComponentInDirectChildren<T>(false);
}
public static T GetComponentInDirectChildren<T>(this Component parent, bool includeInactive) where T : Component
{
foreach (Transform transform in parent.transform)
{
if (includeInactive || transform.gameObject.activeInHierarchy)
{
T component = transform.GetComponent<T>();
if (component != null)
{
return component;
}
}
}
return null;
}
public static T[] GetComponentsInDirectChildren<T>(this Component parent) where T : Component
{
return parent.GetComponentsInDirectChildren<T>(false);
}
public static T[] GetComponentsInDirectChildren<T>(this Component parent, bool includeInactive) where T : Component
{
List<T> tmpList = new List<T>();
foreach (Transform transform in parent.transform)
{
if (includeInactive || transform.gameObject.activeInHierarchy)
{
tmpList.AddRange(transform.GetComponents<T>());
}
}
return tmpList.ToArray();
}
public static T GetComponentInSiblings<T>(this Component sibling) where T : Component
{
return sibling.GetComponentInSiblings<T>(false);
}
public static T GetComponentInSiblings<T>(this Component sibling, bool includeInactive) where T : Component
{
Transform parent = sibling.transform.parent;
if (parent == null) return null;
foreach (Transform transform in parent)
{
if (includeInactive || transform.gameObject.activeInHierarchy)
{
if (transform != sibling)
{
T component = transform.GetComponent<T>();
if (component != null)
{
return component;
}
}
}
}
return null;
}
public static T[] GetComponentsInSiblings<T>(this Component sibling) where T : Component
{
return sibling.GetComponentsInSiblings<T>(false);
}
public static T[] GetComponentsInSiblings<T>(this Component sibling, bool includeInactive) where T : Component
{
Transform parent = sibling.transform.parent;
if (parent == null) return null;
List<T> tmpList = new List<T>();
foreach (Transform transform in parent)
{
if (includeInactive || transform.gameObject.activeInHierarchy)
{
if (transform != sibling)
{
tmpList.AddRange(transform.GetComponents<T>());
}
}
}
return tmpList.ToArray();
}
public static T GetComponentInDirectParent<T>(this Component child) where T : Component
{
Transform parent = child.transform.parent;
if (parent == null) return null;
return parent.GetComponent<T>();
}
public static T[] GetComponentsInDirectParent<T>(this Component child) where T : Component
{
Transform parent = child.transform.parent;
if (parent == null) return null;
return parent.GetComponents<T>();
}
}
}
Put this script somewhere in your project, and that’s already it! All extensions become part of the UnityEngine namespace, so all your scripts using UnityEngine will immediately be able to use it!
To use, simply type transform.NameOfMethod(). If anyone knows of a way to bypass the need of typing “transform.” , I would love to know!
Okay, if in some case anyone will ever come across this thread and get to this comment I want to say: there is a better way. “Transform” implements “IEnumerable” interface which means you can basically loop through every single DIRECT child of transform like this:
Transform someTransform;
foreach (Transform tr in someTransform) {
tr.DoSomething() // Do something to DIRECT children of someTransform
}
You can also get Gameobject reference by explicitly casting. But you can’t use “var” here, as it will return typeof(object)
That’s nice. Please don’t necro-reply to 12-year-old dead threads, it’s against forum rules and very likely most of those people aren’t even here anymore.
If you have a problem, please start your own post… it’s FREE!
How to report your problem productively in the Unity3D forums: