Hey Epoch, here’s how it goes down. A coroutine is just an IEnumerator object, and you make one by just calling a coroutine.
When you do that, nothing happens. It’s like a water pump that needs to have its crank pumped, but nobody is pumping it so it sits there and does nothing.
In Unity there’s a special agreement: if you hand that IEnumerator object into StartCoroutine(), which is a method belonging to the object where that StartCoroutine() call is located, what Unity does is starts “pumping” that water pump for you, every frame, or waiting a bit, or whatever.
Every time Unity “pumps” it, the code runs until the next yield
statement. Based on what you yield, Unity will or will not pump it again, per the agreement.
But the important part is that it is the MonoBehaviour where that StartCoroutine() is called that is running your coroutine. He’s the only guy that knows about it. If he dies, so does your Coroutine. That’s the ownership.
There is nothing preventing you from sticking a little “stub” coroutine script on another object and tell that longer-lived script to run it for you.
That structure in Unity is loosely called a “coroutine runner.” Think of it as a handy motor sitting around waiting for water pumps and it will pump them for you.
Here’s an example: https://gist.github.com/LotteMakesStuff/d179d28f29bc9bb499dc5260e0146154
I haven’t used that one but to me it looks perfectly simple and awesome.
Using the above code, you would use it by putting this in your script:
CoroutineRunner.RunCoroutine( MyOriginalCoroutine());
That’s it. This works beyond when your own script gets destroyed, BUT!!! Remember if your script does get destroyed while this coroutine is still running, if any part of the coroutine code touches any part the Destroyed GameObject, you’ll get errors (such as if you try to move the gameObject where the coroutine is).
But you can do static things like loading scenes after a few seconds, that’s perfectly fine.