Unity Coroutines

I promised some insight into some of the problems Unity presents as a platform for development a while back. There’s no better time to blow off steam discuss those limitations and little land mines than when you’re experiencing one. As some of you might be aware, Unity has support for something called Coroutines for organization of things dependent on order of events, so it shouldn’t be a surprise that we’re utilizing this heavily for our event system.

The pros: You can start these coroutines easily and control the flow just as easily. The StartCoroutine function will take a function from anywhere (like a modular collection of managed event objects that all have different operations like “Walk Over There” and “Pick This Up”), and just fire them off into an autonomous mode. Fire it off and forget it.

The cons: Fire it off and forget it. You can’t stop them easily. There’s only one way to do it, and the implementation (called StopCoroutine, logically enough) is a shabby afterthought. It requires that you use an override of StartCoroutine that (as far as I’m aware) doesn’t support object oriented programming or code reusability, requiring the Coroutine functions you want to fire to be a part of the object doing the firing. The object doing the firing is my Event Manager. The operation needing to be fired is in a separate interface implementation, and for good reason.

Put another way, let’s say I have an Event Management System that handles running all our operations. This is a system separate of the actual implementation of operations. Each type of operation needs it’s own “FireMeOff” function, because they all do different things but there’s no reason for the manager to know what each one needs to do. It should just see the required function is there for the operation and get it running and/or stop it if required to do so. As the Unity team has implemented this, unless every version of “FireMeOff” resides in my Event Manager, there will be no convenient way of stopping the Coroutines that get shot off into digital space.

The apparent solution: Far from elegant … I’ll have to implement the control of my event Coroutines at the operation level, instead of the MANGER level, where it should be. This might include having to edit each operation to include special instruction for flushing out of the Coroutine. Not. Bueno.

The much better solution, which I see no option for: If I were to fire off a Coroutine using StartCoroutine, I would like to be able to store the reference to the Coroutine as the StartCoroutine fires. E.G., Coroutine myCoroutine = StartCoroutine(myFunction());

Ideally, I could then call myCourtine.Stop();

Comments

11 responses to “Unity Coroutines”

  1. gavinfx@yahoo.com Avatar
    gavinfx@yahoo.com

    So you’re saying that you have lots and lots of coroutine “stop” coding to do? That’s sucky.

  2. jeremy@sporktania.com Avatar

    Can’t you just write a wrapper for StartCoroutine() that returns an object with a stop method? Then just wrap whatever IEnumerator gets passed with a function that checks a flag in that custom coroutine object before calling MoveNext() on the enumerator to run the next step, and if it’s been flagged as cancelled, yield break. (Maybe optionally attach a “cleanup” delegate.)

  3. TylerDrinkard Avatar
    TylerDrinkard

    I’m going to try to minimize it to just those events that need it, but essentially “yes”. Instead of a one-stop solution in the proper place, I’m forced to bust out duplicate code everywhere it’s needed.

  4. nockgeneer Avatar
    nockgeneer

    Boo, that’s irritating. It’s like having to code inline css with !important statements everywhere because you don’t have access to the head element and some javascript library is overriding way too much.

  5. ISOHaven Avatar
    ISOHaven

    Pretty much sounds like you’ve gone back in time about 6 years. Ugly old school way of doing it.

    What’s really gonna piss you off is when they fix it on the next release or two and all that ugly extra code will grind away at your soul.

  6. TylerDrinkard Avatar
    TylerDrinkard

    I always have the option of writing a wrapper class that would replace every StartCoroutine function we have. This, too, is a great deal of work initially, but easier to maintain over time. Slightly more elegant than the kludge I proposed, so I may spend an evening to test that out and see if it fits.

    All in all, I’m just disappointed that I have the capability to get a Coroutine reference from StartCoroutine function, but there’s no StopCoroutine function that takes that reference. < /rant > 🙂

  7. arex Avatar
    arex

    is that the kind of thing you could request from Unity?

  8. TylerDrinkard Avatar
    TylerDrinkard

    We could, but it’s been queued in their requests for longer than a year already. Unity, as a company, is heavily focused on bigger and newer functionality, so these smaller requests go more or less on their back burner.

  9. VRDave Avatar

    Boilerplate! Boilerplate! Boilerplate!
    That’s my takeaway from working with Unity coroutines.

    And once you find an elegant, working, clean solution…
    Sell! Sell! Sell!

    No reason not to keep the project afloat by selling your solution to other hungry devs out there.

    ;{p

  10. TylerDrinkard Avatar
    TylerDrinkard

    I thought I’d follow up for anyone interested in the solution I chose. As it would turn out, StartCoroutine that is stoppable can only take one parameter. That was initially painful, because our methods have multiple parameters passed into them for varying circumstances.

    Solution: Create an object array to store the parameters in, then pass the object array as your one parameter to StartCoroutine and parse the parameters on the other side.

    There’s also the limitation that the object reference doing the coroutine stopping should also be the one that started it. This was just blind luck that we were able to rearrange the code very easily to accommodate this restriction. I instantiated the object to which all coroutines were started with, and dropped a StopAllCoroutines bomb on it to kill everything. It works well and I no longer have indigestion from the thought of some horrid workaround.

  11. Johnathon Avatar

    Glad to hear it! Keep forging on, for the Two Guys and for Ace Hardway!!! (and for us 🙂 )

Leave a Reply

Your email address will not be published. Required fields are marked *