Search Unity

Among all the shiny new features, there is a tiny one line in the Unity 5.3 release notes for a feature that I found useful and I think you will too. Custom coroutines, namely the new CustomYieldInstruction class, mean that you can now add your own coroutine yield operations in a very simple way. So let’s take a look at a real world example.

A real world example – A bugfix

I was recently investigating a bug in the UI Dropdown component, a Unity 5.2 feature. When Time.timescale was set to 0, the Dropdown component would only work once, then it would not reappear until timescale was set back to a non-zero value.

After a bit of debugging, we found out that the problem is in the Show function.


m_Dropdown is not null and is preventing the Dropdown from being shown.

Once shown, the m_Dropdown component is minimised and then destroyed. Well, it should be destroyed, but when the timescale is 0, this is not happening.

Take a look at the destroy function and see if you can spot the problem.


The title of this article may have given it away, but WaitForSeconds is the answer. WaitForSeconds uses scaled time. This means that if you tell WaitForSeconds to wait for 1 second and the timescale is 0.5, then you actually wait for 2 seconds (1 / 0.5 = 2). So using WaitForSeconds with a timescale of 0 means that you wait indefinitely (until the timescale is not 0). The Dropdown was never being destroyed after its first use, because we would get held up by the WaitForSeconds yield instruction.

The solution

We need to wait using unscaled time; the most elegant approach here is to add a new yield operation, a WaitForSecondsRealtime class. Clearly, if our own developers do not realise WaitForSeconds uses scaled time, then we need to address this. WaitForSecondsRealtime  should help reinforce this message. We also need to update the docs for WaitForSeconds (we never mention scaled time!).

This is how I discovered the CustomYieldInstruction, recently added for creating new yield operations.

Adding a new yield operation is very simple, here is the solution to our problem.


Any custom yield operation needs to override the keepWaiting property and once we want the yield operation to continue, we just pass back false.

Here is how our fix now looks:


In our example, we grab the real time and just test against it each check. It doesn’t get much simpler than that – oh wait, it does, because we now also have the WaitUntil and WaitWhile yield instructions. With these, we can provide a delegate to be called for our yield instruction test.

Here is an alternative way to solve our problem, assuming we wanted a 5 second delay.


So, a simple feature, but with a lot of potential. I guess the lesson learned here is: Remember to read the release notes, you never know what useful features you might find! If you like the custom coroutines, you should take a look at UnityEvents, another favourite feature of mine that you may have missed.

67 replies on “Custom Coroutines”

Thanks for the post, Karl!

But from what you wrote, I was really worried that CustomYieldInstruction was too limited an API, especially for basic cases where you want to reuse a yield instruction instance to prevent too much GC pressure from high-frequency or persistent waits.

I’m SUPER happy to know, from reading the new documentation, that you can also implement custom yield instructions by just implementing IEnumerator in any arbitrary class.

But then I wondered, was this always the case even before 5.3?
If so, I feel so stupid for not doing it that way before. At the same time though, nobody else seemed to catch on and post about it online in Unity tips blogs so was there something else to that?

Is this only “sugar” ? since it seems that it’s perfectly possible to achieve the same using your own IEnumerator returning method (which will block until certain conditions are met).

With regards to the metnioned UnityEvents – i believe there are some horrendous things going on under-the-hood… something with the ArgumentCache class and its implementation of ISerializationCallbackReceiver. It allocates ridiculous amounts of memory… I think i reported this or only asked about it on the forums. I wonder if there’s something being done about it.

Unless I’m missing something, it seems strange for keepWaiting to be implemented as a property instead of a method.

whydoidoit November 28, 2012 – 10:15 pm That happens when yiendilg in a coroutine the compiler has generated code that MonoDevelop cannot break on it does cause the debugger to appear to step to exit code don’t worry about it, it’s just the magic class doing its return.

It’s great to see CustomYieldInstruction and WaitForSecondsRealtime finally make it into Unity! They will make a big difference.

Hopefully another lesson learned here is the importance of eating your down dog food! The need for CustomYieldInstructions and an unscaled version of WaitForSeconds come up often when using coroutines in a project. Both of which have been requested many times over the past many years. Now if we can just get you to go ahead and add pause, exception handling, return values, and a few other tweaks to coroutines, that’d be great.

I’m really sorry to ask for coriifacatiln on this I wrote an algorithm that creates an rtf javascript editor in a web page. The editor works flawlessly when the javascript file unminified is < 1000 lines. The work around I found for parsing large scripts was to setinterval and time my execution. If it took too long I'd set an interval to release the thread and reenter such that the browser wouldn't display the unresponsive script error.Are you saying this threading code will unlock the HTML ui layer and allow background processing to occur? If what you say is true, and the previous comment about ie supporting a variant of this is true, you could have just rocked my world let me know.M

The problem with nearly everybody having missed Unity Events is that they were never advertised individually and independently from the new Unity 4.6 UI. People only know them from injecting click handlers into buttons and don’t even suspect that you can enable the whole new “mouse only” level of behavioural level design for non-techs. You can barely find some geeky pioneers on the YouTube sharing their “revelations” that, hey, it appears you can actually use Unity Events without the UI.

mick November 28, 2012 – 9:57 pm Question about stepping torhugh DoHijack() with the monodevelop debugger:50IEnumerator DoHijack()51{52while(true)53{54//Check if we have a current coroutine and MoveNext on it if we do55if(_current != null && _current.MoveNext())56{57//Return whatever the coroutine yielded, so we will yield the58//same thing59yield return _current.Current;60}61else62//Otherwise wait for the next frame63yield return null;64}65}When I break on line 59 and then step over (f10), the current instruction caret moves to line 63 even though it doesn’t appear to be executing that line (ie if I set a breakpoint on line 63 it wont’ get hit). What is going on here?

Thank you for this important information.

For a while now, the Timer class in my Waitress library has been supporting unscaled time. It can also be used in non-coroutine methods. You don’t have to implement and start a coroutine to be able to wait for something.

Please see the code examples in documentation if you are interested in more info :

Waitress on Asset Store :!/content/45719

Is it really necessary in 2015 to embed code as an image on a website? Especially on a HiDPI screen these code blocks look like a blurry mess in comparison to the sharp text surrounding it…

Also, where is the documentation of CustomYieldInstruction? I couldn’t find it in the API reference.

I’m trying to work on nested coroutine these days by passing a stack to trace these nested coroutines and their real executing monobehavior. It’s working if I stop all the coroutines by clear the stack, however if I want to stop the top of the stack, the parent coroutine won’t proceed for the terminated coroutine just stopped without any break yield instructions. With this feature I think I can make something useful. However, it would be better if nested coroutine could be supported by Unity natively.

This will be possible, since now Unity properly handles IEnumerator when yielding. Actually CustomYieldInstruction class is just a small handy wrapper based on it:

abstract CustomYieldInstruction: IEnumerator {
public abstract bool keepWaiting { get; }

public object Current { get { return null; } }
public bool MoveNext() { return keepWaiting; }
public void Reset() {}

If you were to return another IEnumerator through Current, then coroutine would be suspended on that.

Not sure but, isn’t the line “m_Items.Clear();” also a bug? For it is inside the “for” instruction so it will clear all the list in the first for step.

It is good news.
but i really miss some features, especially when I do work on state machine code.
I don’t think it big issue to implement for you it is so easy
PauseCoroutine, ResumeCoroutine, Get progress of Coroutine, WaitCoroutine ( make Coroutine pause till another done) , GetCoroutine , … , … and so on
May be also if you add editor window to show all current running Coroutines.

This will make Coroutines amazing full solution for state machine.

Yup. My only point here really is that they are motsly equivalent.Holy cow though I find CPS code to be impossible to read and impossible to debug.We’re getting more and more of it in the world and good god is it ugly.Callbacks are a nasty nasty way to write code.

Does returning ‘false’ from ‘keepWaiting’ guarantee that this object is never used again inside Unity internals, so we can organize a pooling mechanism for these custom yieldables to reduce GC pressure?

With these, we can provide a delegate to be called for our yield instruction test.

yield return new WaitWhile(() => Time.realtimeSinceStartup < waitTime);

Isn't this code generating an anonymous delegate? Means it allocates memory with every execution. I hope that's not real code found in Unity, as I prefer zero GC allocs. Sad enough that using yield already generates garbage, don't need even more of it.

Otherwise it's another feature you can hardly use for periodically called code, unless you don't care about framerate hiccups caused by the GC kicking in every now and then.

This is just a helper class to make it easier to implement simple yield instructions. If you want flexibility or more control, you can now derive from IEnumerator (this is what CustomYieldCoroutine is actually doing, see my answers above).

Very useful indeed, thanks for highlighting it. Any chance the devs could refactor “keepWaiting” to “KeepWaiting”? It is a property, after all.

That would contradict to Unity’s own naming standards, although (which is requested by you) match those of .NET/Mono. I guess Unity guys prefer to stick to, well, Unity standards. Why they introduced their own standards back in the day is now history. There is no and cannot be any final solution about this question, as your code always contradicts either Unity standards, or .NET standards. Unless you invent a time machine, return to the past and change it, your request is meaningless and satisfying it would introduce more inconsistency. Cheers

This looks really cool, thanks for making a blogpost about it! Eventhough i try to read the changelog carefully this one slipped through, and its super useful.

Your code example is clearing the list you are iterating over inside the for loop, so you will not be calling DestroyItem on all the items in the list. Looks like you want to clear the list after the for loop.

Thanks Karl for sharing the new feature. It looks like it will be very useful.

You have a small mistake in your post. 1 x 0.5 = 2 should be 1 / 0.5 = 2

You should actually use Time.unscaledTime (or accumulate Time.unscaledDeltaTime).

Using Time.realTimeSinceStartup will jump ahead unexpectedly if the player pauses the game by tabbing out…

In that case they should also add WaitForSecondsUnscaledTime and not replace the new WaitForSecondsRealtime

“the new WaitForSecondsRealtime” is actually not a new built-in Unity feature but rather an example of how one would build a class inheriting from the new CustomYieldInstruction class (which is a new built-in Unity feature).

Oh, I see what you mean. If they implemented WaitForSecondsRealtime may as well implement WaitForSecondsUnscaledTime in the API.

I still get confused by Coroutines without the custom yield. :-)

Comments are closed.