Do default parameters not work with coroutines?

This seems pretty straightforward: I define a coroutine like so:

public virtual IEnumerator dispense (Task taskOverride = null) {
...

But when I call it at runtime with no parameters, I get “Failed to call function dispense of class Unit_local. Calling function dispense with no parameters but the function requires 1.” I can’t find any online references to this problem. Does it have something to do with my default value being null?

Let me guess, you start the coroutine by string name like so:

StartCoroutine("dispense");

Or you’re using some inspector based thing that calls it reflectively as well.

When called via string (which uses reflection) it expects all the parameters regardless of defaults. Try calling it directly:

StartCoroutine(dispense());

You should avoid the reflection/string based ways of calling methods/properties if you have direct ways readily available. Reserve reflection/string based things for when you want the flexibility it gives (like allowing you to setup things in inspector and serializing it for configurable purposes), remembering that when this is done… there are limitations.

Your guess is correct! That syntax does fix my present problem, but I have to start this coroutine by string because I need to be able to stop it. I haven’t been able to reliably stop coroutines using the syntax you recommend.

You can’t do this:

StartCoroutine(dispense());

// Later
StopCoroutine(dispense()); // Won't do what you're thinking

But you can do one of these:

Coroutine co = StartCoroutine(dispense());

// Later
StopCoroutine(co);



// OR
IEnumerator e = dispense();
StartCoroutine(e);

// Later
StopCoroutine(e);
3 Likes

Good to know. Will the former stop that specific instance of the coroutine, while the latter stops all instances of the coroutine?

I’m not sure what happens if you use the same string to start two coroutines and then call StopCoroutine on that string, but when you’re using the version of StartCoroutine that takes an IEnumerator, there is no way to stop “all instances” of that function. StartCoroutine has no way of knowing what function you called–all it sees is the actual IEnumerator object!

All 3 of the examples I listed attempt to stop the specific “instance” you pass to the StopCoroutine function; the difference is that in the first (non-working) example, that instance is different from the one you passed to StartCoroutine, so Unity has no way to find the one you are trying to stop.

You can stop all coroutines running on the current MonoBehaviour (regardless of which functions they are running) by calling StopAllCoroutines().

1 Like