I have an enemy script that uses a coroutine to dispatch enemies as needed. It works fine and the enemies are sent precisely on time. As the project got bigger I added more coroutines in different scripts doing different things. Now I notice sometimes some enemies are not being sent exactly on time. Im assuming coroutines affect each other in some way since they are all pausing the code?
Corourines just pause the method while continuing the functionality of the rest of the game code.
Coroutines do not interfere with eachother.
Use debug.log to see what happens when to see why this happens
1 Like
How far off are we talkin’ here?
Time is not usually continuous in the computer world. If your coroutine yields WaitForSeconds(10) or something, it’s never going to resume at exactly 10 seconds. It’s going to be scheduled on the next frame after 10 seconds elapses. At the typical frame rate of 60 frames per second, the timing could be as much as 0.016 seconds off. Even more if you have performance slow-downs. This should not be enough for anyone to notice unless you have a bunch of independently acting agents that are supposed to be in-sync.
If we’re talking about more than a second, then it’s probably a bug in your code or something.
kdgalla:
How far off are we talkin’ here?
Time is not usually continuous in the computer world. If your coroutine yields WaitForSeconds(10) or something, it’s never going to resume at exactly 10 seconds. It’s going to be scheduled on the next frame after 10 seconds elapses. At the typical frame rate of 60 frames per second, the timing could be as much as 0.016 seconds off. Even more if you have performance slow-downs. This should not be enough for anyone to notice unless you have a bunch of independently acting agents that are supposed to be in-sync.
If we’re talking about more than a second, then it’s probably a bug in your code or something.
Yes it’s a lot more than a second. I’ll have to recheck the code and see what’s happening.
Coroutines definitely do not do anything like “pause the code.”
Check it:
Coroutines in a nutshell:
Hey Epoch, here’s how it goes down. A coroutine is just an IEnumerator object, and you make one by just calling a coroutine.
When you do that, nothing happens. It’s like a water pump that needs to have its crank pumped, but nobody is pumping it so it sits there and does nothing.
In Unity there’s a special agreement: if you hand that IEnumerator object into StartCoroutine(), which is a method belonging to the object where that StartCoroutine() call is located, what Unity does is starts “pumpin…
Coroutines are an IEnumerator object. They have their own internal state. It's different from just calling InvokeRepeating(), which would restart a fresh function call each time.
Here is ALL you need to know about coroutines in Unity:
they are an IEnumerator, also known in some languages as a Generator. It is an object with a .MoveNext() method on it that "yields" the next thing with each subsequent call. That is what you create by calling an IEnumerator: you create the object, you do NOTHI…
Splitting up larger tasks in coroutines:
Technically, yeah, there’s always a way. But in practice, in the general sense it can get really hairy.
Also, in the particular case of adding lots of GameObjects, I know they’re not linear: last I checked, adding 1000 GameObjects is WAY more than 10x slower than adding 100 Gameobjects, I presume due to inefficiencies in newly-added stuff, not sure/ No way to tell with a closed-source engine like Unity.
Trying to tie into system timers and judge how long things have taken so far will get you …
Coroutines are NOT always an appropriate solution: know when to use them!
The main thing to check before calling / making a coroutine is to ask yourself,
“Does this even need to be a coroutine?”
Generally, if your design requires you to call StopCoroutine(), then don’t make it a coroutine.
If you just need something to happen a bit later, this is a more-robust approach:
https://gist.github.com/kurtdekker/0da9a9721c15bd3af1d2ced0a367e24e
If you’re flipping from one value to another, such as fading in, fading out, changing speeds slowly, etc., coroutines are an AW…
There’s never a need. As @PraetorBlue pointed out in a recent post of his, nobody NEEDS coroutines.
They do solve a certain class of problem nicely however, primarily problems of sequencing a set of data or events to happen.
Coroutines CAN be interrupted and restarted but doing so exponentially increases your chance of a bug, negating a lot of their inherent benefits.
A lot of human behaviors are good coroutines: “Go take a shower.”
So that breaks down to:
get undressed
start the shower
…
Our very own Bunny83 has also provided a Coroutine Crash Course:
https://answers.unity.com/questions/1749615/coroutines-ienumerator-not-working-as-expected.html?childToView=1749714#answer-1749714