I wanted to make a simple diode switching on and off whole time playing and I made the code like this
public IEnumerator IENUM()
{
while (true)
{
for (int x = 0; x <= 6; x += 2)
{
//Do the stuff with delay
}
}
}
My question is, will this affect the game in any way like slowing performance? The game is going to be in this scene only and I don’t want the game to be laggy after an hour or so by e.g. creating too many Coroutines or something. I didn’t see anyone use it this way while searching on different forums.
It’s fine; the yield instructions in the coroutine will prevent the game from freezing, if that’s what you’re worried about.
That said though, if this coroutine is meant to just be running endlessly forever, why not just use Update instead?
I agree with this use case; sometimes it’s just easier to express things this way.
However, let me point out one thing that can bite you with loops inside of infinite loops:
If you do not provide at least SOME kind of yield and allow it to go compute bound, this will lock up Unity.
For instance:
// cycle through aliens, speeding each one up every second or so
while(true)
{
foreach (var alien in alienList.ToArray())
{
if (alien) alien.speedUpALittleBit();
yield return new WaitForSeconds( 1.0f);
}
}
This code will work fine until someone removes every alien from the alienList and then … magical lockup.
ALSO: keep in mind if someone sets this GameObject to inactive, then turns it back on, ALL coroutines running on it will STOP PERMANENTLY. This would not be the case if you tracked the time delay with Update().
Yes, this is a common oversight by some developers. Of course you have to ensure that the infinite loop will always at least after a determind time hit a yield instruction. Also keep in mind while some code is executing inside the coroutine, no other code will run until you hit a yield statement. Coroutines do not run asynchronously but synchronously. It’s cooperative multi tasking. If you do not cooperate (i.e. give the control back to Unity) you will be trapped inside your code and your application will freeze / hang.
To answer the actual question: Using an endlessly running coroutine is definitely better than starting / stopping coroutines all the time. Starting a coroutine requires an object allocation. Once it’s created and running it doesn’t allocate any additional memory (except any allocations you do inside your coroutine of course). So I only see two main usages for coroutines: Either you have rare one-time events like scene fade out / in animations or maybe some download process at the game start. The other kind of coroutines are the infinite running coroutines. Infinite looping coroutines have many advantages. They are quire useful for “modal” behaviour. So you can do something like
IEnumerator MyCoroutine()
{
while(true)
{
while (!Input.GetKeyDown(KeyCode.Space))
yield return null;
// some heavy task or process that requires splitting / spreading over multiple frames
// or just waiting for other things
}
}
The advantage is that while the process is running, you don’t have to care about blocking the triggering key to avoid multiple calls. A common usecase might be a dialog that could be implemented like this