How does this code work. I don't get the foreach loop

  public GameObject enemyprefab;
      
        void Start () {
            foreach (Transform child in transform) {
                GameObject enemy = Instantiate(enemyprefab, child.transform.position, Quaternion.identity) as GameObject;
                enemy.transform.parent = child;
            } 
    	}

I don’t understand this either, could anyone explain? If possible can someone explain the entire code and what each bit is doing and how it works?

The transform reference keyword can access both the actual GetComponent<Transform>() from the GameObject as the GetComponentsInChildren<Transform>() which returns an array of the transforms of all the children of the current GameObject running the script.

foreach loops run one time for each item within an array and allow you to access each of those items during the loop.

In this case, you are instantiating one enemy for each one of the gameobject’s children and then setting this new enemy instance as child of the child currently being accessed by the foreach loop

Sorry forgot to put solved. I used the video from this link to help me with loops in general. If you just want for each loops skip to 4:05.

What link? I still need a bit of help with this.

foreach(Transform child in transform)
{
GameObject enemy = Instantiate(enemyPrefab, child.transform.position, Quaternion.identity) as GameObject;
enemy.transform.parent = child;
}

I don’t understand this part the most; foreach(Transform child in transform)

Can someone break down the entire code for me, please.

Hi @Recable,

The foreach statement is going to iterate through something.

Here’s an example in a slightly different context, but one which may be clearer;

foreach(Person passenger in Car.Passengers)
{
    // do something for each person in the car
}

In the above, the code would iterate through a collection of Person objects named Passengers, which belong to the Car object.

On each iteration, the enumerator, passenger, is set to the next instance of a Person in the collection.

The foreach statement will repeat until all of the objects are iterated over, or if you exit out of the loop early using other code.

In the code block between the { and } characters you can access this object via passenger, perhaps;

    Debug.Log("Passenger name : " + passenger.Name);

Now, back to your specific example;

foreach(Transform child in transform)
{
    GameObject enemy = Instantiate(enemyPrefab, child.transform.position, Quaternion.identity) as GameObject;
    enemy.transform.parent = child;
}

The foreach statement iterates through transform which can be either a single Transform, or, a collection which contains many Transform objects.

The enumerator is named child, you can name this anything you wish, it is effectively a variable used for the iteration. You could call it childTransform for example.

Transform is the type of the enumerator.
transform is the transform component of the game object.

The code between the { and } characters will be repeated for each child transform that exists.

Hope this helps.


See also;

4 Likes

Thanks for this, it’s made it a lot clearer now, also thanks to Joao for trying to help me too, I’m just a bit slow at certain coding topics.

You are more than welcome.

If you come up against anything else, just post, chances are you will be helping someone else who wasn’t so comfortable asking. :slight_smile:

Hi Joao_Dalvi:
there is one point i don’t understand here, i always think the transform keyword only access to the game object which it attached to. But now i understand that it can also access to the transform of children game objects. what i confused is how the transform keyword decide which game object it should access, the parent game object or the children game objects?

as when i applied the script, the enemies only appeared at the positions of children objects but not at the parent’s position.

could you answer me this question if you can, please? thanks.

1 Like

Hello Ben, how are you?

It decides based on the type of the object, if it is required to return a Transform (not array), which seems to be the default return type, it will return the actual GetComponent<Transform>() of the object, although if the expected return type is an Array of Transforms, it will return GetComponentsInChildren<Transform>() , please note that the transform of the object itself isn’t returned in this case, only the childs. Since you can’t run a foreach without a Collection (arrays, lists etc.), it will then use the reference to the array of child’s transforms.

But this is hard to know how this exactly works under the hood since we don’t have the source code of the unity itself.
The “transform” variable is just something to speed up the code and make it simple, since pretty much all GameObjects have transforms, they added it as an inbuilt variable.

3 Likes

Thank you very much, Joao. You explain it very clear. now i understand how transform keyword work a little bit more. :smiley:

2 Likes

No problem, I’ve made some tests here and I wasn’t able to use the transform reference as array or lIst in other situations, so I’m not sure if it would work in other cases other than in the foreach loop.I think that don’t make too much of a difference knowing exactly how it works under the hood since it is just a variable that they added to help us, we could add one ourselves that could do something similar for example.

2 Likes

thanks Joao. like what you said, it is a quick and convenience way, if it didn’t work somewhere else, we can just use GetComponentsInChildren() directly. it’s readability better in my opinion :smiley:

1 Like

Probably the most confusing bit in the lectures so far. Thanks to everyone that helped explain this!

The transform component being the handle for parent/child blew my mind. I was expecting it to be GameObject. :slight_smile:

Hey Harvey,

Because every GameObject has a Transform component they are often used a little inter-changeably. If you have access to a Transform, you have access to the GameObject, and vice-versa.

Privacy & Terms