Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

GameObject Relationships - GetChild

Discussion in 'Scripting' started by padomu, May 9, 2014.

  1. padomu

    padomu

    Joined:
    Sep 8, 2013
    Posts:
    51
    Hi,

    I just talked in the IRC chat about how to get a child GameObject. We discussed the architecture a bit and I found it rather interesting.

    So, Unity has the concept of GameObject and Components, right?

    you create a GO and add the Components you need. You can give a GO a child GO etc

    That children concept, what is it about? The child is relative in it's position, scale etc. so the childs transform extends the parents transform. Thats good, makes sense.

    I looked up several way of getting the child object, and there is not nice way. People are using soemthing like parent.transform.whatever. why isn't the GameObject Class managing relationships?

    I'd have expected something like:

    this.GetChild("Foo"); return child named "Foo"
    this.GetChild(0); returns first Child (sucks anyway)
    this.GetChildren(); returns List of Children of type GameObjects

    Why is it, the way it is? I'm not complaining, just curious.

    I know I could use the Inspector, but I don't like it. I prefere to do it via code.
     
  2. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    Code (csharp):
    1.  
    2. this.transform.Find("Foo"); // returns the transform of the child named "Foo"
    3. this.transform.GetChild(0); // returns the transform of child with index 0
    4.  
    5. // You can do this to go through each child.
    6. foreach (Transform aChild in transform) {
    7.   Debug.Log("Found a child transform with name " + aChild.name);
    8. }
    9.  
    10. // I generally will do stuff like this
    11. List<SomeClass> aBunchOfObjects = new List<SomeClass>();
    12. SomeClass newObject = (new GameObject("Foo")).AddComponent<SomeClass>();
    13. aBunchOfObjects.Add(newObject);
    14.  
     
  3. DarkArts-Studios

    DarkArts-Studios

    Joined:
    May 2, 2013
    Posts:
    389
    I have the following internal script which I (re)use within my own projects:

    Code (csharp):
    1.  
    2.        public static GameObject FindRecursivelyWithinChildren(GameObject gameobject, string name)
    3.         {
    4.             foreach (Transform transform in gameobject.transform)
    5.             {
    6.                 if (transform.gameObject.name == name)
    7.                     return transform.gameObject;
    8.             }
    9.  
    10.  
    11.             GameObject foundGameObject = null;
    12.  
    13.  
    14.             foreach (Transform transform in gameobject.transform)
    15.             {
    16.                 foundGameObject = FindRecursivelyWithinChildren(transform.gameObject, name);
    17.                 if (foundGameObject)
    18.                     return foundGameObject;
    19.             }
    20.  
    21.  
    22.             return null;
    23.         }
    24.  
     
  4. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    I think you guys are missing the point. He's more asking why those methods aren't in GameObject.

    GameObjects do not contain other GameObjects - instead Transforms contain other Transforms. The most direct implementation of this concept is that Transform implements the IEnumerable interface which allows you to use a foreach loop to traverse children.

    My guess is that Unity did this simply to gain more direct access to positions, rotations, and scales in order to apply those properties relatively. But - I don't work for Unity so I can't answer definitely :)
     
  5. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    Yeah, it's a little weird. It's the child that defines who its parent is, and not the parent who defines who the children are. It makes sense though that the transform takes care of this, as the child operates within the parent's transform in the matrix stack.
     
  6. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    I see. Yeah I'm going to go with RockoDyne and say it is because of how matrix math works.

    Eg: All verticies in a model have a position. This position is multiplied by a matrix representing the GameObject's local position/rotation/scale, which was multiplied by a matrix representing it's parent's local position/rotation/scale, up the chain until the matrix is multiplied by the camera's viewport to determine location on a 2D screen. EDIT: I might have the directions of the multiplication wrong. Matrix multiplication is NOT commutative!

    Because 3D fundamentally uses matrix math and needs the position/rotation/scale of parent objects, it makes sense that object hierarchy and position/rotation/scale are part of the same Transform class.
     
    Last edited: May 9, 2014
  7. hadiai

    hadiai

    Joined:
    May 10, 2014
    Posts:
    9
    I use the following extension method to get a certain child from a transform. You could write a wrapper extension for GameObject:

    public static Transform GetChild(this Transform inside, string wanted, bool recursive = false)
    Code (csharp):
    1. {
    2.   foreach (Transform child in inside) {
    3.    if (child.name == wanted) return child;
    4.    if (recursive) {
    5.     var within = GetChild(child, wanted, true);
    6.     if (within) return within;
    7.    }
    8.   }
    9.   return null;
    10.  }