Search Unity

A more flexible coroutine interface

Discussion in 'Scripting' started by chomp, Jun 23, 2011.

  1. chomp

    chomp

    Joined:
    Dec 6, 2010
    Posts:
    22
    I've often wanted to do things with coroutines that Unity's API does not explicitly provide an interface for. Namely:

    • Get a handle to a specific coroutine, with which I can:
      • Pause and unpause the coroutine
      • Stop the coroutine
      • Ask if the coroutine has terminated
    • Start a coroutine from library code that is not directly aware of any MonoBehaviour instance
    • Receive notification whenever a coroutine terminates
    • Not write code to do these things every time I need them!

    I've also recently had a discussion with someone else who was interested in these same sort of features, but who lacked the ability to implement them. So I present a simple TaskManager script that makes this all much simpler. The source is here:

    https://raw.github.com/krockot/Unity-TaskManager/master/TaskManager.cs

    The comments document usage.

    In a nutshell, this allows you to - with no initialization and from anywhere in any code - do things like:

    Code (csharp):
    1.  
    2. // Equivalent to StartCoroutine(SomeCoroutine())
    3. new Task(SomeCoroutine());
    4.  
    5. // Equivalent to the above, but keeps a handle to the running coroutine
    6. Task t = new Task(SomeCoroutine());
    7.  
    8. // Pause the coroutine at next yield
    9. t.Pause();
    10.  
    11. // Resume it
    12. t.Unpause();
    13.  
    14. // Terminate it
    15. t.Stop();
    16.  
    17. // Test if it's still running.
    18. if(t.Running) {}
    19.  
    20. // Test if it's paused.
    21. if(t.Paused) {}
    22.  
    23. // Receive notification when it terminates.
    24. t.Finished += delegate(bool manual) {
    25.     if(manual)
    26.         Debug.Log("t was stopped manually.");
    27.     else
    28.         Debug.Log("t completed execution normally.");
    29. };
    30.  
    I hope someone finds this to be useful. Cheers!
     
    JGroxz, yakuphan, nahoang304 and 7 others like this.
  2. runner

    runner

    Joined:
    Jul 10, 2010
    Posts:
    865
    Thank You

    looks handy :cool:
     
  3. Sam at FPS

    Sam at FPS

    Joined:
    Sep 1, 2009
    Posts:
    80
    Nice work. I've been frustrated with the lack of flexibility in coroutines before. This looks like a nice addition to my library. Cheers.
     
  4. faultymoose

    faultymoose

    Joined:
    Oct 1, 2010
    Posts:
    246
    I was only just crying into my coffee last night about being unable to pause/resume coroutines! I thankyou sir, and so does the taste of my coffee! <3
     
    Harinezumi likes this.
  5. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,603
    Very nice share, thanks :)

    Though I'm unsure to what degree its really usefull cause coroutines still run in the main thread so why would i really want to pause them, its not that you would do longer term stuff in them if you ever want to debug your code again, get it working right and leave any cpu time to anything else ;)

    The real gain to me is the explicit stop from a handle :) thats the major pain we all had as unity coroutines lack on that end as not even string handles help, it required to use Invoke which is troublesome in its own way
     
  6. Julien-Lynge

    Julien-Lynge

    Joined:
    Nov 5, 2010
    Posts:
    122
    Thank you for this! I'm running a data visualization using unity and am pulling data with WWW calls from multiple servers in parallel, and this really makes my job easier. If you put this in the asset store (and sent me an email reminder) I would gladly pay money for this.

    As someone with a non-programming background, forgive the naivety, but as an academic exercise would it be possible to take this code a step further and write it as an extension for the (useless) Coroutine class? Extension is just a static class with carefully defined methods, right? Could you add static variables to that class to mimic things like Running that the extended Coroutine would have access to? Or write them as methods (bool isRunning())?
     
  7. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,603
    See no use in extending coroutine as coroutine is just a dummy container.
    the "is it running or not" is a thing that the managing host class etc in the end defines (here task) as its responsible for making the coroutine run at all. a coroutine can't manage itself, it can not even exist on its own (it only exists in context of MonoBehaviour so if I were to add such capabilities somewhere it would be an extension to monobehaviour)
     
  8. Felix Schlitter

    Felix Schlitter

    Joined:
    Sep 30, 2013
    Posts:
    8
    Thanks for sharing, I learned a good deal from the source code. Thanks again for not charging 15 dollars on the Asset store for this as seems to be the trend
     
  9. softrare

    softrare

    Joined:
    Jun 12, 2011
    Posts:
    429
    Hi! Well done! May I use this in my Asset Store package?
     
  10. WillNode

    WillNode

    Joined:
    Nov 28, 2013
    Posts:
    298
    Thank you for sharing that, I always use that for tweening things (because it's look handy).

    FYI, i have some better improvement from your code (i did a fork to your code ;) ), take a look on here:
    https://github.com/willlandmubarok/Unity-TaskManager

    it's about a coroutine system which uses delegates (more simple and powerful), so you can ...

    Code (CSharp):
    1.  
    2. void Start() {
    3.     //Tweens from (0,0,0) to (1,0,0) for 20 seconds
    4.     Task.Get(delegate(float t) { transform.position = new Vector3(t,0,0); }, 20);
    5. }
    6.  
     
  11. AdamRamberg

    AdamRamberg

    Joined:
    Dec 8, 2016
    Posts:
    16
    Great! Thanks for sharing :)
     
  12. kwiplimited

    kwiplimited

    Joined:
    Oct 23, 2017
    Posts:
    1
    How would you tell when the coroutine is finished?
     
  13. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    4,550
    You put a command at the end of the coroutine which tells you that it has run and ended. Like you call a function or something.
     
  14. Supergeek

    Supergeek

    Joined:
    Aug 13, 2010
    Posts:
    93
    As a hobbyist, this little module is just what I was looking for. Simple enough to integrate into my repertoire; one class that's easily integrated instead of a complex, sprawling suite with more functionality than I need.
     
  15. JGroxz

    JGroxz

    Joined:
    Dec 12, 2017
    Posts:
    9
    Put simply, this is awesome. Gives much more flexibility with Coroutines, especially when using singletons. Kudos for it!