StartCoroutine gets the arglist type wrong

In the following Unityscript code snippet, the line containing the StartCoroutine gives the compile time error “No appropriate version of 'UnityEngine.MonoBehaviour.StartCoroutine' **for the argument list '(void)'** was found.” As you can see, the argument list is in no way void.

Switching to string call syntax (instance.StartCoroutine("FadeInAgain", source)) gives no compile errors, but at runtime, the error message “Coroutine 'FadeInAgain' couldn't be started! UnityEngine.MonoBehaviour:StartCoroutine(String, Object)”.

This behaviour is all the more puzzling as the exact same call sequence works perfectly in other contexts, even in the same source file. (The code below is the smallest version of the file which still gives this error.)

I should also point out that omitting the “static” declaration for the coroutine makes no difference, neither does rearranging the order of the function definitions.

Any ideas?

#pragma strict
#pragma downcast

static var instance : AudioManager;

function Awake() {
    instance = FindObjectOfType(AudioManager) as AudioManager;
}


static function RestoreAffectedSounds(source : AudioSource) {
    instance.StartCoroutine(FadeInAgain(source));
}


static function FadeInAgain (source : AudioSource) {
    Debug.Log("Hello");
}

I’m not 100% sure, but I think error can also trigger if source is null. Try checking for null before doing the StartCoroutine.

There is a check in the complete code for null, but in this case the error is triggered compile time. There is no way for the compiler to know that the arg is null at that time, unless it’s typed that way or can be inferred to be null statically.

Ah, I believe I see the issue now. Your FadeInAgain does not contain yield, so Unity thinks it is a normal function with no return value (void). If you add yield somewhere, it should properly mark it as a coroutine (IEnumerator).

Wrong syntax.
Here is the Description
Starts a coroutine named methodName.

// In this example we show how to invoke a coroutine using a string name and stop it

function Start () {
StartCoroutine(“DoSomething”, 2.0);
yield WaitForSeconds(1);
StopCoroutine(“DoSomething”);
}

function DoSomething (someParameter : float)
{
print(“DoSomething Loop”);

}

You can type the function as IEnumerator:

static function FadeInAgain (source : AudioSource) : IEnumerator {

The syntax is not wrong. Most of the time you don’t want the string version.

Static functions can’t be coroutines. Coroutines can have many instances, but static means there can only be one instance.

–Eric

They can, actually. You just need to make sure they only work on their input values and don’t read/write any static variables. I have occasionally used static Coroutines. It can be useful if you need some generic Coroutine functionality that is used in many scripts. I think the functionality the OP is trying to use it for is actually quite a good example of where static Coroutines are useful.

@tomvds: Thanks! Adding a yield fixed it, as does adding a return type of IEnumerator, of course. This also explains why the error was intermittent: I could successfully start other coroutines in the same source file using exactly the same kind of syntax, but then they already contained a yield. In this case, I was stubbing things out during development, so the coroutine was entirely bare.

I can’t remember seeing anything in the reference manual about extra compiler processing of methods containing yields, though, but it of course makes sense.

@Eric5h5: tomvds is right, static methods can be used as coroutines. The usage here is quite deliberate.

Thanks everyone! Much appreciated.