Quickly retrieving the immediate children of a GameObject

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!

1 Like

Look no further than at the first piece of example code in the scripting reference for the Transform class:

Rune

5 Likes

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;
    }
1 Like

No need to iterate twice and use specific arguments:

public static T[] GetComponentsInDirectChildren<T>(this Component parent) where T : Component
        {
            List<T> tmpList = new List<T>();

            foreach (Transform transform in parent.transform)
            {
                T component;
                if ((component = transform.GetComponent<T>()) != null)
                {
                    tmpList.Add(component);
                }
            }

            return tmpList.ToArray();
        }

Well as long as we’re necro-ing an ancient thread, this is even simpler:

transform.Cast<Transform>().SelectMany(t => t.GetComponents<Whatever>());
2 Likes

To get the immediate childs use gameobject.transform and traverse it using
foreach(Transform eachGameObject in gameobject.transform){

}

1 Like

DID SOMEBODY SAY OPENING UP AN OLD THREAD?!?!?!

How about THIS?!

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!

Peace out!

10 Likes

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)

1 Like

But… I used that in my code as well :’)

Actually, now that I’m scrolling through the thread, almost everyone is already suggesting this in some form or another.

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:

http://plbm.com/?p=220

If you post a code snippet, ALWAYS USE CODE TAGS:

How to use code tags: https://discussions.unity.com/t/481379