Search Unity

Quickly retrieving the immediate children of a GameObject

Discussion in 'Scripting' started by phort99, Jan 21, 2010.

  1. phort99

    phort99

    Joined:
    Oct 20, 2009
    Posts:
    76
    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:
    Code (csharp):
    1. parent
    2.   child1
    3.     grandchild1
    4.   child2
    5.     grandchild2
    6.  
    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:
    Code (csharp):
    1. Transform[] children = transform.GetComponentsInChildren<Transform>();
    2.  
    3. foreach (Transform child in children)
    4. {
    5.     if (child.parent == transform)
    6.         child.GetComponent<SomeComponent>().DoSomething();
    7. }
    It seems like an omission that you can very easily access the parent but not the children!
     
  2. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,636
  3. phort99

    phort99

    Joined:
    Oct 20, 2009
    Posts:
    76
    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.
     
  4. DreamTitan

    DreamTitan

    Joined:
    Dec 19, 2015
    Posts:
    5
    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:

    Code (CSharp):
    1. public static T[] GetComponentsInDirectChildren<T>(GameObject gameObject)
    2.     {
    3.         int indexer = 0;
    4.  
    5.         foreach (Transform transform in gameObject.transform)
    6.         {
    7.             if (transform.GetComponent<T>() != null)
    8.             {
    9.                 indexer++;
    10.             }
    11.         }
    12.  
    13.         T[] returnArray = new T[indexer];
    14.  
    15.         indexer = 0;
    16.  
    17.         foreach (Transform transform in gameObject.transform)
    18.         {
    19.             if (transform.GetComponent<T>() != null)
    20.             {
    21.                 returnArray[indexer++] = transform.GetComponent<T>();
    22.             }
    23.         }
    24.  
    25.         return returnArray;
    26.     }
     
    MrLucid72 likes this.
  5. PutridPleasure

    PutridPleasure

    Joined:
    Mar 3, 2015
    Posts:
    11
    No need to iterate twice and use specific arguments:

    Code (CSharp):
    1. public static T[] GetComponentsInDirectChildren<T>(this Component parent) where T : Component
    2.         {
    3.             List<T> tmpList = new List<T>();
    4.  
    5.             foreach (Transform transform in parent.transform)
    6.             {
    7.                 T component;
    8.                 if ((component = transform.GetComponent<T>()) != null)
    9.                 {
    10.                     tmpList.Add(component);
    11.                 }
    12.             }
    13.  
    14.             return tmpList.ToArray();
    15.         }
     
  6. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,298
    Well as long as we're necro-ing an ancient thread, this is even simpler:

    Code (csharp):
    1. transform.Cast<Transform>().SelectMany(t => t.GetComponents<Whatever>());
     
  7. jayant304

    jayant304

    Joined:
    Jul 7, 2017
    Posts:
    3
    To get the immediate childs use gameobject.transform and traverse it using
    foreach(Transform eachGameObject in gameobject.transform){

    }
     
    vivalavida likes this.
  8. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    12
    DID SOMEBODY SAY OPENING UP AN OLD THREAD?!?!?!

    How about THIS?!

    Code (CSharp):
    1.  
    2. using System.Collections.Generic;
    3.  
    4. namespace UnityEngine
    5. {
    6.  
    7.     public static class UnityEngineEx
    8.     {
    9.  
    10.         public static T GetComponentInDirectChildren<T>(this Component parent) where T : Component
    11.         {
    12.             return parent.GetComponentInDirectChildren<T>(false);
    13.         }
    14.  
    15.         public static T GetComponentInDirectChildren<T>(this Component parent, bool includeInactive) where T : Component
    16.         {
    17.             foreach (Transform transform in parent.transform)
    18.             {
    19.                 if (includeInactive || transform.gameObject.activeInHierarchy)
    20.                 {
    21.                     T component = transform.GetComponent<T>();
    22.                     if (component != null)
    23.                     {
    24.                         return component;
    25.                     }
    26.                 }
    27.             }
    28.             return null;
    29.         }
    30.  
    31.         public static T[] GetComponentsInDirectChildren<T>(this Component parent) where T : Component
    32.         {
    33.             return parent.GetComponentsInDirectChildren<T>(false);
    34.         }
    35.  
    36.         public static T[] GetComponentsInDirectChildren<T>(this Component parent, bool includeInactive) where T : Component
    37.         {
    38.             List<T> tmpList = new List<T>();
    39.             foreach (Transform transform in parent.transform)
    40.             {
    41.                 if (includeInactive || transform.gameObject.activeInHierarchy)
    42.                 {
    43.                     tmpList.AddRange(transform.GetComponents<T>());
    44.                 }
    45.             }
    46.             return tmpList.ToArray();
    47.         }
    48.  
    49.         public static T GetComponentInSiblings<T>(this Component sibling) where T : Component
    50.         {
    51.             return sibling.GetComponentInSiblings<T>(false);
    52.         }
    53.  
    54.         public static T GetComponentInSiblings<T>(this Component sibling, bool includeInactive) where T : Component
    55.         {
    56.             Transform parent = sibling.transform.parent;
    57.             if (parent == null) return null;
    58.             foreach (Transform transform in parent)
    59.             {
    60.                 if (includeInactive || transform.gameObject.activeInHierarchy)
    61.                 {
    62.                     if (transform != sibling)
    63.                     {
    64.                         T component = transform.GetComponent<T>();
    65.                         if (component != null)
    66.                         {
    67.                             return component;
    68.                         }
    69.                     }
    70.                 }
    71.             }
    72.             return null;
    73.         }
    74.  
    75.         public static T[] GetComponentsInSiblings<T>(this Component sibling) where T : Component
    76.         {
    77.             return sibling.GetComponentsInSiblings<T>(false);
    78.         }
    79.  
    80.         public static T[] GetComponentsInSiblings<T>(this Component sibling, bool includeInactive) where T : Component
    81.         {
    82.             Transform parent = sibling.transform.parent;
    83.             if (parent == null) return null;
    84.             List<T> tmpList = new List<T>();
    85.             foreach (Transform transform in parent)
    86.             {
    87.                 if (includeInactive || transform.gameObject.activeInHierarchy)
    88.                 {
    89.                     if (transform != sibling)
    90.                     {
    91.                         tmpList.AddRange(transform.GetComponents<T>());
    92.                     }
    93.                 }
    94.             }
    95.             return tmpList.ToArray();
    96.         }
    97.  
    98.         public static T GetComponentInDirectParent<T>(this Component child) where T : Component
    99.         {
    100.             Transform parent = child.transform.parent;
    101.             if (parent == null) return null;
    102.             return parent.GetComponent<T>();
    103.         }
    104.  
    105.         public static T[] GetComponentsInDirectParent<T>(this Component child) where T : Component
    106.         {
    107.             Transform parent = child.transform.parent;
    108.             if (parent == null) return null;
    109.             return parent.GetComponents<T>();
    110.         }
    111.     }
    112. }
    113.  
    114.  
    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<YourComponent>(). If anyone knows of a way to bypass the need of typing "transform." , I would love to know!

    Peace out!
     
    Last edited: Jul 5, 2018
    Lu_Atar, OlaBrahammar and path14 like this.