Hey guys. I am having some troubles with understand how coroutines work. All I know is that they work as threads, which allows for calculations over a timeframe instead of just one frame.
Essentially I want to run a coroutine every 0.5 seconds. The setup I have now works, but I know it can be improved. I have a boolean which is set to true when the routine is started, and set to false when the routine is finished.
The coroutine usually takes < 0.025 seconds to complete, before it waits for half a second. Then it restarts. Second problem is how can I improve this. First problem is that I barely understand how this works. Thrid problem is the lag.
The coroutine performs a check on 100 objects inside a foreach loop. When I try to run this it lagged. Then I added this code inside the loop, and the lag was gone.
if(itemNr % 23 == 0) yield return new WaitForSeconds(0.01f);
From what Ive heard about coroutines I shouldnât need to add this line in a coroutine?
My coroutine chain of events:
bool = false â start coroutine â set bool to true â do X checks â wait a bit â repeat checks and wait until Y checks have been performed â wait for 0.5 seconds â set bool to false â yield return false â repeat
TLDR:
What is the difference between yield return true, false and null? Can someone explain to me what yield return actually does, as if I was a third grader? What is the best/slickest (not necessarily easiest) way to repeat a coroutine every time it finishes? If I try to start a coroutine which is already running, what will happen?
Yield return 0, false and null all wait one frame and continue from the next line.
You can use co routines for timed things without dealing with deltatime calcs by taking advantage of WaitForSeconds as well as making an FSM with them.
To repeat a co routine inside itself you can use while (true) inside it and put all your logic there, then when it finishes it will start again because the condition true is constant.
Else, you can just StartCoroutine(ThisName()) again when it reaches the end of it. You need at least one yield return inside it to prevent infinite loops.
Starting a coroutine always starts a new one. Think of then as instances. If you use the latter to do so, make sure itâs not in a while(true) loop or the starter will never end and youâll create new routines indefinitely without any ending.
Itâll wait one frame. Though always use ânullâ since true/false/0/etc. are value types, and will have to get boxed in memory and cause unnecessary garbage. Long story short⌠it will cause hiccups in your game.
An iterator function allows you to define a function that programmatically defines an enumerable list of data. While some code is enumerating over that data, the code is generating the next piece of data on demand. The âyieldâ statement is saying âthis is the next value to return in the listâ. And because itâs coded⌠you can have conditions for if you yield it, or what is actually yielded.
Unity now took this idea and figured to themselves.
What if we allow you to write a list of instructions. And we âforeachâ it one tick every frame. This means that the code between yield statements occurs in a frame and then we can wait for the next frame.
And with yield instructions like âWaitForSecondsâ we can have quick easy representations for common actions⌠instead of yielding null for a duration of time, unity interprets this WaitForSeconds object as meaning to do that.
Thanks alot @LaneFox and @lordofduct ! This helped shorten my code alot, and made it alot easier to read. I still have some small questions like why is there a yield return null, true AND false, if they all do the same? But these can all be answered by a quick google search I would imagine, and if they canât itâs not a big deal.
Thereâs nothing that unity doesnât allow to be returned, because the IEnumerator enumerates over the type âobjectâ, which all types in .Net/Mono can be treated as âobjectâ.
Itâs a matter of what unity determined giving meaning to.
They put meaning to a few types, which usually inherit from YieldInstruction. Things like:
Where as everything else, no matter it be boolean, int, GameObject, whatever⌠they all get treated the same, which is the default bahaviour of the coroutine. And that is⌠wait one frame.
Not exactly at the third grade level, but I found this explanation dramatically aided my understanding of coroutines. Itâs quite technical, but it helped me to be aware of whatâs under the hood.