Coroutines and my headache

Ok, so here’s my dilemma.

I’ve been using IEnumerators since I jumped into Unity to do small delays as needed. I always do something like this, and it’s no sweat.

void Start()
{
    StartCoroutine(TimedExecution());
}


IEnumerator TimedExecution()
{

    yield return new WaitForSeconds(1);
    Debug.Log("A second has passed since this object was created");

}

However, I ran into an issue today where an object, that is not disabled, or destroyed, or being influenced by timescale in any fashion, will not execute anything after the yield statement.

I was doing some reading to understand a little bit better, and it seems that they are supposed to stop executing after the yield statement? That doesn’t make sense to me, but that seems to be happening with this one object and it’s execution of the coroutine.

In the same project, I have a coroutine executed in the same fashion, the WaitForSeconds portion is at the beginning of the IEnumerator, and it still continues to execute… but this object that gets instantiated with it’s own coroutine decided that it doesn’t want to do anything after that yield. Any yield.

The only thing that may be relevant is that this object is being spawned from an additive scene, but I don’t think that’s the issue. Any insight is welcome. Cheers!

They just mean that a yield will stop the execution of the function for that frame, it will pick up where it left off next frame until it encounters another yield or it finishes execution. That’s how the coroutine runs over multiple frames.

Why does it never continue? I put that Debug.Log line in there and it’s not executing, but if I remove it, it does.

you can find the answers for the most of your questions neatly explained here

yield is a contextual keyword that is exclusively used in enumerators, and it was introduced for accessibility reasons. in other words, it’s a language feature that is processed exclusively by the compiler, without any changes to how the base enumeration works.

in other to understand how it all worked, you should really go to the beginning, to the actual IEnumerator interface that is used to enable the foreach clause on a custom collection.

more read here:

to do this, historically, you would have to introduce a new class that would hold the state of the iterator and have Reset(), MoveNext(), and Current property included. however, after a certain version of C#, you were allowed to declare a method as IEnumerator or IEnumerable and by using yield, compiler would do the mundane work for you, creating the class for you and decorating it as necessary.

then Unity came along, and made this feature, that normally had nothing to do with TIME or frames – but was merely iterating over a series – into a coroutine. it’s clever, but completely non-intuitive for the beginners, and I do not say that lightly, I’ve worked with a dozen languages, and the amount of headaches with coroutines is something you typically get from jumping into Perl after doing an Excel table, and I’m not sure why every beginner in the world absolutely immediately jumps on it, like it’s a silver bullet of sorts.

it’s an excellent hack when you really need something done in a quick and dirty way, like waiting a second, but the real power lies in understanding the enumerators in the first place. in my work, I’ve done some interesting setups with ‘yield’ to debug my algorithms, let them iteratively progress through time, show me step-by-step progression and such, without having to use the coroutines at all.

Make a minimum repro and report it as a bug. I suspect that in making a minimum repro, you will find the reason why this is happening.

Is anything being destroyed? The original caller owns it. If an IEnumerator in B is run by a StartCoroutine in A then destroying A stops it (if the coroutine uses member variables in B, and B is destroyed, I’m not sure what happens).

Nothing is being destroyed at this point.

For everyone’s clarification, I had to change that IEnumerator to a regular public void, and from a different script on the same object, I created an IEnumerator just for the delay WaitForSeconds(1) and then ran that method and it began to work correctly.

For further clarification, this is a networked game project using Mirror and Unity 2018. Not sure if that has anything to do with it.