Admittedly, a really silly “issue”, but why does unity not throw an error when you call a coroutine without the start coroutine function? For example, in both Unity and Visual Studio, calling a coroutine like “foobar();” is totally fine, even though it does nothing and the actual way to call it is “StartCoroutine(foobar())”.
So my question is does calling “foobar();” actually do anything? If not I suggest Unity throw a warning at least when someone tries to do that.
Thanks
Unity calls them coroutines but what you’re writing are basic C# iterator methods.
They can be used for all kinds of things besides coroutines and for Unity it cannot be clear if a given iterator method is intended to be used for a coroutine or for something else. You can also instantiate the enumerator from a iterator method, pass it around in your game logic and call StartCoroutine
at some later point in time.
Unity doesn’t have a good way to determine if someone has forgotten to call StartCoroutine
or if they are using iterator methods in some other way and there’s no appropriate place to trigger an error message.
Depending on your IDE, there might be a Unity plugin with some analyzers that will at least show a warning if you discard the enumerator. E.g. in VSCode using the Unity extension, it shows “Coroutine ‘MethodName’ should be called using StartCoroutine()”.
Things are also moving away from coroutines towards async/await. When Unity originally implemented coroutines, iterator methods where the best thing they could use, but it always wasn’t what iterator methods were intended for. Later, C# added async/await, which directly implements coroutines into C# and which makes more sense for Unity to use.
Using async/await, there’s no more need to call StartCoroutine
or the danger of forgetting it.
From Unity 2023, you can use Awaitable as a replacement for coroutines. For older versions, you can use UniTask.
IEnumerator is a C# thing, for an object that defines how to enumerate something: IEnumerator Interface (System.Collections)
Though nowadays we pretty much always use the strongly typed generic IEnumerator<T>
when writing our own custom enumerators. You technically could when writing coroutines, as it IEnumerator<T>
does implement IEnumerator
too, though no real reason to do so.
Still, knowing how to write one is useful. Here’s an example of one that just writes to console n number of times: C# Online Compiler | .NET Fiddle
But a method returning an IEnumerator
is like any other method that returns a value. You can call said method without caring about the return value. It’s just a normal C# thing to do.