Problems with Yield

This is not complicated code. The most important thig is that i take each child move it back one spot, if its too far back I delete it. It works, I think, unless I uncomment the yields. It all moves so fast I can’t confirm if the Instantiation happens properly, but when I try to slow it down with a yield, everything breaks, each object flys back to infinity and hits delete but not really, because then I get “MissingReferenceException: The object of type ‘Transform’ has been destroyed but you are still trying to access it.” Even though the object is still flying back. So why does yield break my code? And how can I slow down unity so that I can see whats going on?

function Move ()
{
    var i : int = 0;
    for (var child : Transform in transform)
    {
        //childPos = child.position;
        child.position.z--;
        //yield WaitForSeconds(2);
        if(child.transform.position.z < -1)
        {
            Destroy(child.gameObject);
        }
        if(child.tag == "Tail" && i != 5)
        { 
            newTail = Instantiate(Strait, child.position,  child.rotation);
            newTail.tag = "Tail";
            newTail.transform.parent = transform;
            child.tag = "Untagged";
            i++;
        }
        //yield WaitForSeconds(2); 
    }
}

I think it won’t work the way you use the coroutine here. I guess you run Move every frame from Update, right? If you turn your function into a coroutine (when you use yield) you will start a new coroutine every frame and they will run side by side until they are finished. You would start a huge amount of couroutines which all do the same. You can’t slow down your game this way. Update will run every frame, no matter what you do.

You could run your Move from a CoUpdate and yield it in there so everything else in there would stop until your Move coroutine is completed.

To avoid null references and problems with the transform IEnumerator you should do it like this:

function Move ()
{
    // create a local copy of the current childs.
    // this list will stay the same, even when we destroy objects
    var childs = transform.OfType.<Transform>().ToList();

    var i : int = 0;
    for (var child : Transform in childs )
    {
        child.position.z--;
        yield WaitForSeconds(2);
        if(child.tag == "Tail" && i != 5)
        { 
            newTail = Instantiate(Strait, child.position,  child.rotation);
            newTail.tag = "Tail";
            newTail.transform.parent = transform;
            child.tag = "Untagged";
            i++;
        }
        if(child.transform.position.z < -1)
        {
            Destroy(child.gameObject);
        }
        yield WaitForSeconds(2); 
    }
}

As i said, to make this work you have to use some kind of CoUpdate like this:

function Start()
{
    while(true)
    {
        yield StartCoroutine(Move());
    }
}

You must never destroy the items of a for…in (or foreach, in CS) loop - this screws up the loop control, and you may have all kind of weird effects. You could use a regular for instead, like this:

 for (var n: int = 0; n < transform.childCount; n++){
    var child: Transform = transform.GetChild(n);
    child.position.z--;
    ...

NOTE: Despite GetChild isn’t documented in the docs, it seems to be safe enough (the FPS Tutorial uses it, for instance).