is it proper to call coroutine as a normal method?

I have:

void Start()
    {
        StartCoroutine(MyCoroutine());
        MyCoroutine();
    }

    IEnumerator MyCoroutine()
    {
        Debug.Log("Coroutine started");
        yield return new WaitForSeconds(1);
        Debug.Log("Coroutine finished");
    }

Is this proper practice? or would it be better to add a new method like:

void Start()
    {
        StartCoroutine(MyCoroutine());
        MyCoroutine();
    }

    IEnumerator MyCoroutine()
    {
        Debug.Log("Coroutine started");
        yield return new WaitForSeconds(1);
        Debug.Log("Coroutine finished");
    }

    void MyCoroutine()
    {
        Debug.Log("return void started");
        //
        Debug.Log("return void finished");
    }

what is best?

the USE-CASE is that sometimes I want to call the code I have on my coroutine, but I dont want it to yield, I want it to run the whole code and skip all the yields

is it best practice to just make a new method with the same name that is not ienumerator, or can I still call the coroutine, just without the startcoroutine() syntax?

1 Like

Calling a coroutine like a normal method won’t actually do anything. It just returns an IEnumerator object, but unless you call MoveNext() on the IEnumerator the code in the coroutine won’t be executed.
You could do this:

IEnumerator coroutine = MyCoroutine(); // create the coroutine
while (coroutine.MoveNext()) {} // execute it until the very end

All StartCoroutine() does is pass the IEnumerator to Unity, and tell it to automatically advance the coroutine until it’s done.

5 Likes

so what do you prescribe for my usecase? can i create a method with the same name, except i make it public void?

Either execute the coroutine manually as I suggested above, or make a method with a different name. You can’t have two methods with the same name and same parameters, because it is impossible for the compiler to know which one you’re calling.

3 Likes

Sounds like you want to spend a little time familiarizing yourself with Coroutines. Coroutines in a nutshell:

Splitting up larger tasks in coroutines:

Coroutines are NOT always an appropriate solution: know when to use them!

“Why not simply stop having so many coroutines ffs.” - orionsyndrome on Unity3D forums

Our very own Bunny83 has also provided a Coroutine Crash Course:

hmm thanks but not quite, i can handle coroutines, my question was more specific rather than broad

Ran into this problem too occasionally. There isn’t a way to reuse the method and somehow treat it sometimes as a non-coroutine. That’s because there’s some compiler magic happening in the background when yield statements are involved.

Best solution is to do what arkano22 said, but you can wrap that into an universal custom helper function which contains that while loop.

Something like:
void CoroutineAsFunc(IEnumerator the_coroutine) (can’t write it out right now from phone).

1 Like

One old trick is to turn everything it does into it’s own function and let the co-routine/non-co-routine be drivers:

IEnum myCoroutine() {
  while( .. ) {
    stuff(); // these used to be lines in the coroutine
    yield return ...
  }
}

Now you can call stuff(); to run the “coroutine” just one time.

Of course that won’t work very well if your coroutine looks like "important variables, stuff, yield, change variables, stuff2, yield … ". In that case a hack might be adding an “instant” flag:

IEnum myCoroutine(bool runWithYields=true) {
  ...
  if(runWithYields) yield ...
  ...
  if(runWithYields) yield ...
  ...

  yield return null;
  // coroutines need at least 1 yield or you get yelled at
}

Passing bools always confuses me, so I decided false was the “run the funny way” version. You’d still have to use StartCoroutine, but you could write a driver to hide it void myCoroutineInstant() { StartCoroutine(myCoroutine(false));.

1 Like

Would recommend not to do that because at some point you will forget that this is still a coroutine, call it directly and then wonder why it doesn’t do anything ><
Been there, done that…

4 Likes