0
\$\begingroup\$

I have been thinking about the use of Unity's coroutines recently, and while I've used them in the past, and am already aware of their bad reputation (although I've also seen posts on the unity forums of people who seem to absolutely swear by them), the more I think about it, I'm kind of struggling to see any compelling reasons to use them at all instead of simply creating a new component and simply performing the logic of the coroutine in said new component's Update method. By using a IEnumerator coroutine inside of another component, it seems to me like all it accomplishes is decreasing the cohesiveness of individual components and the re-usability of the component using them.

Is there any convincing argument to actually use coroutines in Unity and would I be missing out by simply not using them? Are there any scenarios I'm overlooking where their use would either be required or prove incredibly useful?

\$\endgroup\$
3
\$\begingroup\$

You can do that if you want, but...

First, 10000 update calls are more expensive than one update call calling 10000 functions. This is due to the Magic Method indexing and querying logic Unity does for you.

Second, adding, removing, and fetching components has its own overhead. And it's not a cheap as you think. It isn't heavy, but you absolutely don't want to be calling GetComponent every game for dozens of objects.

Third, some methods you do not have control over return an IEnumerator (namely, Web requests) and the only sensible way to call these is in a coroutine.

Fourth, it can actually fragment your code even more than a coroutine seems to, because its now in a separate class chock full of timers and counters, other state machines and callbacks, plus even further calls out to more coroutine replacements when you have a coroutine that invokes further coroutines...

Fifth, coroutines can, in a single method, pick up and execute code in no less than four different places in the Update cycle loop, and sometimes you need the ability to wait until after LateUpdate, but before rendering, then wait again until just before Update...Admittedly a rare scenario, but plausible.

But in the end, coroutines are just another tool. It can be used well, it can be used poorly, or not at all.

\$\endgroup\$
  • \$\begingroup\$ Nice. Your first, third and last points are especially interesting. As for your second and fourth though, isn't coupling between components by linking them in the inspector done exactly to avoid the use of getcomponent in a scenario like this, and if your coroutine's lifecycle was as complex as you set out in your fourth point then wouldn't that actually be an argument in favor writing a new component class? (an example would be very much appreicated to demonstate what you mean here!) \$\endgroup\$ – ZombieTfk Jan 4 at 7:15
  • \$\begingroup\$ Linking components in the inspector does cut down on the lookups, yes, but you can't always do this. Think about a coroutine you would use to monitor, say, a power-up effect. You wouldn't want that script to exist all the time, you'd only want it to exist when it was needed. As for the complexity, not necessarily. A coroutine that waits for a coroutine isn't that complex, it's just a function call inside a function. \$\endgroup\$ – Draco18s Jan 4 at 14:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.