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?
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.
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.
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).
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));.
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…