Safe Coroutine overcomes several limitations of Unity's coroutines and provides you with flexible controls. Main Features - Stopping of any safe coroutine - Pausing and resuming - Nesting - Exception handling - Returning of typed results - Source code Converting your code to use safe coroutines is straight forward. Example Code (csharp): // // Author: // Andreas Suter (andy@edelweissinteractive.com) // // Copyright (C) 2014 Edelweiss Interactive (http://www.edelweissinteractive.com) // using UnityEngine; using System.Collections; using Edelweiss.Coroutine; namespace Edelweiss.Examples { public class SafeCoroutinesExample : MonoBehaviour { private SafeCoroutine m_SafeCoroutine; private void Awake () { m_SafeCoroutine = this.StartSafeCoroutine (ExampleCoroutine ()); } private IEnumerator ExampleCoroutine () { while (true) { yield return (null); } } private void OnGUI () { GUILayout.Label ("Safe Coroutine State: " + m_SafeCoroutine.State); GUILayout.BeginHorizontal (); GUI.enabled = m_SafeCoroutine.IsSelfPaused; if (GUILayout.Button ("Resume")) { m_SafeCoroutine.Resume (); } GUI.enabled = m_SafeCoroutine.IsRunning || (m_SafeCoroutine.IsParentPaused !m_SafeCoroutine.IsSelfPaused); if (GUILayout.Button ("Pause")) { m_SafeCoroutine.Pause (); } GUI.enabled = m_SafeCoroutine.IsRunning || m_SafeCoroutine.IsPaused; if (GUILayout.Button ("Stop")) { m_SafeCoroutine.Stop (); } GUILayout.EndHorizontal (); } } }
Thanks for the interest. I am surprised that there is already positive feedback, even if no one couldn't try it out so far
That feels like getting a trustworthiness diploma It seems that the review took longer than usual recently, so try to stay cool meanwhile
I'm also interested in this package. two features i would like to see to make the package "complete" in comparison to similar packages: pushing the coroutine back and forth between Unity's main thread and a background thread. serializing the state of a coroutine into a binary (or arbitrary) formatter so it can be saved to disc or sent over network. (note: whydoidoit's Radical Coroutines do this by using reflection of the inner states of a gameobject) i don't know how much work is involved with these feature requests or if they are possible at all. But maybe you could consider them.
Even if both ideas kind of sound interesting, I struggle to see use cases that make sense in an actual production. When code is being executed outside of the main thread, it can't e.g. perform any MonoBehaviour calls, unless there is a special solution for that. But in that case, it is good to be aware that something special is happening and to consciously consider that when coding. There are pretty good solutions for threads available like https://www.assetstore.unity3d.com/#/content/3847 . I believe that coroutines and threads should not be merged. I wasn't aware of Radical Coroutines up until now. To be honest, I never though about serializing a safe coroutine and I am really unsure whether it is a good idea to serialize them at all. Right now, I can only see cases where this may lead to invalid application states, so it feels pretty dangerous and unstable to me and I think there are probably better solutions for that than serializing coroutines themselves. Having that functionality in UnitySerializer can somehow make sense, but integrating serialization into safe coroutines that can't serialize its internal state at all... Do you use serialization for coroutines in an actual production? And could you explain me, why you decided to use it and nothing else? If I had a marketing department, they would probably kill me after such an answer I could have written that I thank you a lot for those ideas and consider them for a future release and bla bla bla. As I don't have any use cases in mind that can only be achieved like that or it would be far more complex to achieve them, I don't see a reason to have that kind of functionality. But please, feel free to name me use cases that are relevant in a production environment.
killing is bit harsh, but torturing ... . i'm aware of that. thats why some packages allow to run a coroutine in a thread and when it needs access to unity main thread stuff join it in and after that let it run again in a separate thread. i have sent you a pm with some examples to avoid advertising other packages. albeit i have not used it yet it seems quite handy to me. i have tried the package of whydoidoit a while back and found it way too bloated and dependent. so i could not extract the coroutine stuff i need and i did not want to include the whole package as i run my own serialization and want more controll. so currently i don't use coroutine serialization. what do you mean with "nothing else"? to me a coroutine is a black box and so i cannot know in which state it is when i want to save the game and more importantly i cannot resume it from that state later on after loading. so i must find "workarounds" which lead to coroutines not beeing useable for the things i thought they should be used for. a more or less artificial usecase example: a missile is started, travels to the target, the missile is removed and an explosion spawned and after it has finished it is also removed. i have not worked on the weapon handling in detail just collected some thoughts about it so maybe i'm doing it wrong. sure there may be other ways to accomplish this but are coroutines a completely improper way? if not then beeing not able to save them is still a hindrance and thats why i asked what you think about this. anyway. please don't feel obligated to add this stuff. i was just curious what you think about it. your package has some nice features (esp. exceptions) and thus it would be cool to have features i have seen in other packages in one place. having them distributed over packages (currently i have 3 or 4 at hand) requires to decide which is needed most in which case and choose the used package and also to learn several packages. kind of inconvenient. thats why i asked. i see this could be a big struggle to add and don't know if its worth it for you (revenue) and other users. maybe see what other people think about it. thanks anyway for the discussion.
As I said, I have no marketing department . Though I appreciate it, that you didn't post the links! https://www.assetstore.unity3d.com/#/content/15717 https://www.assetstore.unity3d.com/#/content/15106 https://www.assetstore.unity3d.com/#/content/2597 https://www.assetstore.unity3d.com/#/content/3586 I am going to have a look at them. If you tell me what kind of access you would need to serialize a safe coroutine, let me know. Maybe we find a solution like that. Supporting one serialization may absolutely be possible, but would be too restrictive for my taste. So if I could provide some kind of API to allow the serialization and deserialization, I would absolutely be open to implement that as long as there is a maintainable solution with a clean API. What I meant with "nothing else" was, and not any other solution than serializing the coroutines. In my opinion a coroutine should never contain state information that is relevant to resume a game. You would want to be able to save the game while a missile is being shot and then resume at this point some days later? It would be very uncommon to allow that. Thanks for the feedback. I am always open to discuss!
Just one thing: You mentioned in your video, that there is only one limitation: One can't yield a Unity Coroutine inside a SafeCoroutine. The question: When using your SafeCoroutines, is there still any need using Uniy Coroutines? SafeCoroutines give so much control (Pause, Resume, Stop. Maybe "Rewind" in the future, too?), why should I still use Unity Coroutines, especially inside SafeCoroutines?
There is no need to use Unity coroutines anymore if you have Safe Coroutines. It was mentioned for the sake of completeness. Rewind doesn't exist and is not planned at the moment.
Safe Coroutine was updated. It now contains state change notifications. The video was updated as well.
Bought! I might not get to use this for awhile. Wish I had this a month ago, there were 2 great things I could have used it for. Thanks for making this.
Do safe coroutines persist even if the script is disabled and re enabled? Unity's coroutines are killed if you disable the script, which really annoys me.
The answer is unfortunately no. As you disable a script, all its safe coroutines will also be stopped. Safe coroutines rely on Unity's coroutines, that's why the behavior regarding disabling scripts is identical.
You may consider to implement your custom extension method for that. Just create a new game object that is unknown to all others as much as possible. As you then e.g. perform a call like: Code (csharp): this.StartYourCoroutine (...); It is supposed to forward the execution to that special game object, that may even be created dynamically as needed.
Thanks for this asset, it is just what we needed and you saved us a lot of time. Simple, easy to learn and very professional, we wrote a review in the Asset Store to help you gain some attention We are planning to jump to Unity 5 anytime soon, will this package also work there, or do you need to update it first (don't know how Assets work in Unity 5)?
Thanks a lot for the kind words Safe Coroutine already works in Unity 5. The versions for Unity 4 and 5 are identical. As far as I know, you can only see that there is a version for Unity 5, if you open the Asset Store in Unity 5.
Hello! I am very interested in this asset, and I am wondering if this asset has been tested with WebGL in Unity 5.x? Dies this asset rely on the .NET threading libraries? Thank you for any feedback.
The last time I checked it with WebGL, it worked without any issues. It doesn't rely on any threading library, but only on Unity's coroutines. As such it is only using a single thread.
Thank you for the prompt feedback. What I am hoping to achieve is to "block" on a coroutine until it is finished; specifically, my games rely on certain data being available from a WebSocket (using the WebGL socket example published by Unity) before the game manager class can finish initializing. How can I use your asset to wait until a CoRoutine is finished before executing the next statement in a method?
You can even achieve that with Unity's coroutine. Just start a coroutine, execute the required functionality in it and as the last step you finish the initialization. With Safe Coroutine, you may subscribe to such a safe coroutine and let the finish initialization be executed after the coroutine is done. However, for this use case, you don't get an actual advantage and you should rather stick to using Unity's coroutines.
Hello Dantus! I have a question. When I put a safe coroutine to download a huge file on android, can I pause the download and resume it by user interation or when the application is paused and goes to background? Thanks!
Hi, there! So I'm noticing a specific issue when pausing: if I start a SafeCoroutine, let it hit a `yield return new WaitForSeconds(10f)` wait for >10 seconds, and then resume it, the SafeCoroutine will resume at the end of the WaitForSeconds line, even though it was paused during it. In other words, it seems that the timer for a WaitForSeconds will "keep counting" even while paused. Notably, the SafeCoroutine will not go past the yield -- just right at the end. All the same, this is a decently sizable problem, and I'd love to know if there's a workaround!