Hey guys,
As the title says, how do I write coroutines inside of class (note they’re not MonoBehavior). Is there a way to approach this kind of problem?
Thanks! ![]()
Hey guys,
As the title says, how do I write coroutines inside of class (note they’re not MonoBehavior). Is there a way to approach this kind of problem?
Thanks! ![]()
You can create them but a MonoBehaviour instance is required to run them. You can run Coroutines not included in the MonoBehaviour that is running them by creating a method that takes an IEnumerator
public class CoRunner : MonoBehaviour
{
public static CoRunner Instance { get; private set; }
void Awake()
{
Instance = this;
}
public void Run(IEnumerator cor)
{
StartCoroutine(cor);
}
}
public class AnotherClass
{
void Foo()
{
CoRunner.Instance.Run(Do());
}
IEnumerator Do()
{
yield return new WaitForSeconds(3);
Debug.Log("Done!");
}
}
Thank you! This seemed to fix the problem.
Also, is this a commonly used practice? Does it affect overall performance in any way?
Yes.
No.
It’s also worth noting that you don’t need the wrapper method at all since StartCoroutine is public. So you could technically do this
CoRunner.Instance.StartCoroutine(Do());
I like to encapsulate the behavior though.
This is gold! Thank you once again ![]()
It’s actually more efficient in some ways to have lots of non-MonoBehaviour classes that use a single in-game object to run any in-scene code that’s needed. I have a standard singleton that I plug in to projects which I use for injecting threaded output into Unity’s thread. I use delegates and events for this purpose, which means there is some allocations and thus garbage (can’t wait for the new garbage collector), but there is a performance impact to Unity’s “magic” methods (Update and such),
Of course, you don’t want to do all of your processing this way, but my profiler results have been impressive, and I haven’t even begun taking real advantage of the multi-threading options this opens up.
Coroutines are part of MonoBehaviour. So they cannot run without a MonoBehaviour. You have to do something like @KelsoMRK suggested and run them on a MonoBehaviour. If you go this route, I would actually suggest doing lazy instantiation with static methods.
I would also caution that excessive use of coroutines can lead to messy and difficult to follow code. Tread carefully, before you go starting a coroutine on random objects, think if you really need it, or if there is a better way to complete your task.
Seconded. About the only time I use a coroutine is when I need a loading screen.