Skip to main content
added 323 characters in body
Source Link
user15805
user15805

Normally, this is not allowed in Mono and throws an exception. Unity apparently suppresses thisit and tells you nothing. Here's what actually happens in your code:

Awake()
{
    Transform obj = InstantiateTarget();
    //While there are no children attached to this transform;
    while (transform.childCount > 0) /*Not an infinite loop
                                     because on each step you're removing
                                     a child from this transform
                                     (read on for the explanation).*/
    {
        //Try to attach each child to obj
        foreach (Transform t in transform)
        {
            t.parent = obj; /*The first "t" gets attached, but you're also 
                            altering the collection (this.transform loses track of t). 
                            The foreach loop stops completely! 
                            Since you're executing the foreach loop for 
                            as long as this.transfom has children, you 
                            essentially remove one child transform at a time on 
                            each 'while' pass.*/
        }
    }
    Destroy(gameObject);
}

Normally, this is not allowed in Mono and throws an exception. Unity apparently suppresses this and tells you nothing. Here's what actually happens in your code:

Awake()
{
    Transform obj = InstantiateTarget();
    //While there are no children attached to this transform;
    while (transform.childCount > 0)
    {
        //Try to attach each child to obj
        foreach (Transform t in transform)
        {
            t.parent = obj; /*The first "t" gets attached, but you're also 
                            altering the collection (this.transform loses track of t). 
                            The foreach loop stops completely! 
                            Since you're executing the foreach loop for 
                            as long as this.transfom has children, you 
                            essentially remove one child transform at a time on 
                            each 'while' pass.*/
        }
    }
    Destroy(gameObject);
}

Normally, this is not allowed in Mono and throws an exception. Unity apparently suppresses it and tells you nothing. Here's what actually happens in your code:

Awake()
{
    Transform obj = InstantiateTarget();
    //While there are no children attached to this transform;
    while (transform.childCount > 0) /*Not an infinite loop
                                     because on each step you're removing
                                     a child from this transform
                                     (read on for the explanation).*/
    {
        //Try to attach each child to obj
        foreach (Transform t in transform)
        {
            t.parent = obj; /*The first "t" gets attached, but you're also 
                            altering the collection (this.transform loses track of t). 
                            The foreach loop stops completely! 
                            Since you're executing the foreach loop for 
                            as long as this.transfom has children, you 
                            essentially remove one child transform at a time on 
                            each 'while' pass.*/
        }
    }
    Destroy(gameObject);
}
Source Link
user15805
user15805

It's actually Unity's fault for being quite confusing here. You are not allowed to alter a collection that you're enumerating with a foreach loop. Suppose this:

List<string> SomeList = new List<string>();
//add items to the list
foreach (string s in SomeList)
{
    SomeList.Remove(s); //WRONG! You cannot alter the collection here. Use a for loop instead!
}

Normally, this is not allowed in Mono and throws an exception. Unity apparently suppresses this and tells you nothing. Here's what actually happens in your code:

Awake()
{
    Transform obj = InstantiateTarget();
    //While there are no children attached to this transform;
    while (transform.childCount > 0)
    {
        //Try to attach each child to obj
        foreach (Transform t in transform)
        {
            t.parent = obj; /*The first "t" gets attached, but you're also 
                            altering the collection (this.transform loses track of t). 
                            The foreach loop stops completely! 
                            Since you're executing the foreach loop for 
                            as long as this.transfom has children, you 
                            essentially remove one child transform at a time on 
                            each 'while' pass.*/
        }
    }
    Destroy(gameObject);
}

Use a for loop instead and, as a rule of thumb, every time you write a foreach loop, ask yourself if you're not actually trying to remove items from the collection. If you are, stop right there and use the for loop instead.