Is there a way to run coroutines in classes which does not inherit from monobehaviour? Or is there any other way to use yield return null in such a class?
4 Answers
4You need a MonoBehaviour to tap into Unity’s Coroutine system. As mentioned by Bonfire Boy the yield syntax is not Unity specific so in theory you could write your own Coroutine scheduler, but there are much easier ways.
Here are two options:
- Create an new GameObject and add a MonoBehaviour component to it and use this to call StartCoroutine.
- Have a MonoBehaviour in the scene that acts as your Coroutine caller. Use this to start the coroutine.
And here is a sample implementation for the first case:
coroutineHandler = new GameObject("_coroutineHandler");
coroutineHandler.AddComponent<MonoBehaviour>();
coroutineHandler.StartCoroutine(YourCoroutine());
you can’t , the only way to do this is to create another class that inherits from monobehaviour and
inside it create an instant of the class that doesn’t inherit from monobehaviour and call it’s methods from the instant.
Is there a way to run coroutines in classes which does not inherit from monobehaviour?
I’m not sure, but I have a theory:
The StartCoroutine() method is what makes the Coroutines work, but it is non-static, meaning it requires an instance of a MonoBehaviour (or derived) class in order to be called. That said, it’s also public, meaning it can be called by any class that has a reference to that instance.
What I mean is that the following code will possibly work.
using UnityEngine;
using System.Collections;
class Test
{
MonoBehaviour mono;
public void StartMyCoroutine()
{
mono = new MonoBehaviour();
mono.StartCoroutine("myCoroutine");
}
private IEnumerator myCoroutine()
{
while (true)
{
//Do stuff...
yield return null;
}
}
}
If the above code doesn’t work, then I’m afraid the answer is a very simple “no :/”.
HOWEVER!
If you’re not on a MonoBehaviour derived class, then Coroutines are probably not what you want. Instead, try using Threading: https://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx
Or is there any other way to use yield return null in such a class?
Yes, since yield is a C# keyword: yield statement - provide the next element in an iterator | Microsoft Learn
Perhaps you'd like to check the accepted answer? A MonoBehaviour needs to exist in the scene to be considered active. Therefore an unattached new MonoBehaviour won't actually do anything as it doesn't get Unity Engine events. You need to attach it to something in the scene, which could be an existing GameObject you know about or you can create a new one (per my answer above).
– HuacanachaI actually wrote that right after the question was asked, but no moderators accepted it in time... -.-"
– RamlockTrue. I actually expected that, but it was worth the try ^^ In any case, I still have no idea why he wants so badly to use a coroutine outside a monobehaviour, it doesn't make any sense to me... My guess is that he just doesn't know how to use threads, which would probably be way better/cleaner.
– RamlockYou can run any public method in any class as coroutine. You can call a coroutine only from a monobehaviour-class.
Can you explain the first sentence? For example, how would I run function B in the following as a coroutine? public class A { public void B() { }; }
– Bonfire-BoyThe answer is incorrect, or at least confusingly written. To run a method as a Coroutine it needs to be in a specific format (i.e. returns an IEnumerator) and does not necessarily need to be public. I expect they mean that you can call a Coroutine style method directly and it will execute like a standard function, but you can only get the Coroutine behaviour by calling it in a StartCoroutine on a Monobehavior.
– Huacanacha
Yes to the second question.
– Bonfire-Boyyieldis a C# iterator thing, it's not Unity-specific. The function it's used in has to returnIEnumeratororIEnumerable, and the proscription againstrefandoutparameters is part of C# too. You could have one in any class.you can bypass the ref issue with a delegate: IEnumerator MyCoroutine(System.Action<bool> action) //Bool for the example, any type will do { // Some stuff action(false) // more stuff maybe yield return null; // Could be more there action(true); // or even there } And you use it: bool myBool = false; StartCoroutine(value => myBool = value);
– fafase