Need help understanding "Controlling GameObjects Using Components" page

Hey guys,

I’m having a little trouble understanding the example in the “Finding Child Objects” section of this page http://docs.unity3d.com/Manual/ControllingGameObjectsComponents.html

public class WaypointManager : MonoBehaviour {
    public Transform[] waypoints;
   
    void Start() {
        waypoints = new Transform[transform.childCount];
        int i = 0;
       
        foreach (Transform t in transform) {
            waypoints[i++] = t;
        }
    }
}

I understand that waypoints is an array of Transform components. I also get that the length of the array is initialised to the number of child objects under the parent.

So far, so good.

Unfortunately, there are two separate elements that I can’t wrap my head around:

PROBLEM 1
I don’t understand the use of transform in foreach(Transform t in transform).

In my mind, transform refers to the Transform Component of the parent object (i.e. the object that the script is attached to). Given that a foreach statement is used to iterate through an array, I can’t understand exactly what’s happening here.

PROBLEM 2
The article states that “The child objects can be retreived using the parent’s Transform Component (since all GameObjects implicitly have a Transform)”.

I don’t understand how I’m getting access the child objects using this approach. At best (if I understood Problem 1), I can see how I might be able to access their Transform components, but I don’t see anywhere where I’m getting access to GameObjects.

Any help that anyone can provide would be greatly appreciated.

Thanks in advance.

Matt

Problem 1:

The foreach statement in C# allows you to iterate through any object that implements the IEnumerable interface. The interface defines the methods that’s needed to iterate through the object as a collection of things.

Arrays are IEnumerable, just like Lists, Dictionaries, HashSets, and so on. The Unity devs made the Transform class IEnumerable too - if you look at the available metadata, the Transform class has this signature:

public class Transform : Component, IEnumerable { ... }

If you care about the specifics

To be more specific, the IEnumerable interface exposes a method named “GetEnumerator”, which returns an IEnumerator. The IEnumerator interface has two methods that’s important here - Current, which is the current element, MoveNext(), which sets the next element as Current, and returns true if the iteration isn’t finished.

So, during compilation, this thing here:

foreach(Transform t in transform) {
    DoSomethingWith(t);
}

is turned into something similar to this:

IEnumerator e = transform.GetEnumerator();
while(e.MoveNext) {
    Transform t = (Transform) e.Current;
    DoSomethingWith(t);
}

For problem 2, each transform has access to it’s game object, just like any other component. So if you need to print the name of every child GameObject of your GameObject, this code does it:

Debug.Log("All the children of the gameObject " + gameObject);

foreach(Transform t in transform) {
    Debug.Log(t.gameObject);
}
2 Likes

That’s a hugely helpful response, Baste. Thanks a lot for taking the time to write it up.