hello,
i have multiple coroutines and i want certain ones to run in certain conditions so my simple question is can i have an if statement were i check if a coroutine is running?
void InvokeMyCoroutine()
{
StartCoroutine("Coroutine");
}
IEnumerator Coroutine()
{
CR_running = true;
//do Stuff
yield return //Whatever you want
CR_running = false;
}
// As long as you a within this scope you can just do :
void AnotherFunction()
{
if (CR_running)
{
// Do some other stuff;
}
}
Why not create a quick framework to handle this? After reading all the comments on this page, I had several ideas of my own that all begin with my own custom StartCoroutine method.
PLEASE NOTE: This is experimental code only and is not optimized at all. This is only to serve the purpose of a prototyped idea.
I would do something similar to this:
public class TrackedCoroutineBehaviour : MonoBehaviour
{
private List<string> runningCoroutinesByStringName = new List<string>();
private List<IEnumerator> runningCoroutinesByEnumerator = new List<IEnumerator>();
public Coroutine StartTrackedCoroutine(string methodName)
{
return StartCoroutine(GenericRoutine(methodName, null));
}
public Coroutine StartTrackedCoroutine(IEnumerator coroutine)
{
return StartCoroutine(GenericRoutine(coroutine));
}
public Coroutine StartTrackedCoroutine(string methodName, object parameter)
{
return StartCoroutine(GenericRoutine(methodName, parameter));
}
public bool IsTrackedCoroutineRunning(string methodName)
{
return runningCoroutinesByStringName.Contains(methodName);
}
public bool IsTrackedCoroutineRunning(IEnumerator coroutine)
{
return runningCoroutinesByEnumerator.Contains(coroutine);
}
public void StopTrackedCoroutine(string methodName)
{
if (!runningCoroutinesByStringName.Contains(methodName))
{
return;
}
StopCoroutine(methodName);
runningCoroutinesByStringName.Remove(methodName);
}
public void StopTrackedCoroutine(IEnumerator coroutine)
{
if (!runningCoroutinesByEnumerator.Contains(coroutine))
{
return;
}
StopCoroutine(coroutine);
runningCoroutinesByEnumerator.Remove(coroutine);
}
private IEnumerator GenericRoutine(string methodName, object parameter)
{
runningCoroutinesByStringName.Add(methodName);
if (parameter == null)
{
yield return StartCoroutine(methodName);
}
else
{
yield return StartCoroutine(methodName, parameter);
}
runningCoroutinesByStringName.Remove(methodName);
}
private IEnumerator GenericRoutine(IEnumerator coroutine)
{
runningCoroutinesByEnumerator.Add(coroutine);
yield return StartCoroutine(coroutine);
runningCoroutinesByEnumerator.Remove(coroutine);
}
Bool solution as @Headworker suggested might be the quickest but it can’t handle the CoRoutine break. So i wrote my coroutineX as usual, but then i added:
This script on the Assest Store ($25) has an “isRunning()” method which is what you’re asking for. But I would be interested to hear an answer about how to do this directly.
If you need this just to start/continue 2nd coroutine after 1st has finished, just like I did, you could yield return StartCoroutine(routine). Unity documentation with an example
I didn’t know about it for some time, so after looking at this question’s answers, I used yield return new WaitWhile(() => coroutineIsRunning), where coroutineIsRunning was set to true before starting that coroutine, and was set to false at the end of the coroutine block.
This is an ancient thread but I had an issue with this and the best solution I found was :
//this is what keeps track
Coroutine coroutineToWatch;
//this is how you call it
public void OnlyOneCoroutineRunningAtOnce(){
if(coroutineToWatch!=null) StopCoroutine (coroutineToWatch);
coroutineToWatch= StartCoroutine(TheThingToWatch());
}
//this is the Coroutine
private IEnumerator TheThingToWatch(){
int counter=0;
while(true){
counter++;
print (counter);
yield return new WaitForSeconds(1);
}
}
This has the added benefit of being available from outside using System.Collections; since calling OnlyOneCoroutineRunningAtOnce() doesn’t need Collections… I usually group all my Coroutines as part of some manager class and then have the access methods that wrap them to ensure there is only one instance running at one time.