How can I pass a ref (AudioClip) into a coroutine?

I want to be able to call a function with two parameters, a ref AudioClip and a filename string, and for it to change the audio file in that AudioClip.

Everything else works, I am just struggling on how to get the AuioClip ref into the coroutine.

This is how I call the function:

changeSound(ref xSound, "Weapons/guit00chug.wav");

This is the function:

public void changeSound(ref AudioClip clipToChange, string filename){
		StartCoroutine (LoadAudio (result => clipToChange = result, filename));

That throws this error:

error CS1628: Parameter `clipToChange' cannot be used inside `lambda expression' when using `ref' or `out' modifier

But if you just change the “clipToChange” to “xSound” manually in the StartCoroutine, it works fine:

	public void changeSound(ref AudioClip clipToChange, string filename){
		StartCoroutine (LoadAudio (result => xSound = result, filename));

Does anyone have any idea how to approach this? Any help much appreciated!

EDIT: There is no problem with the string parameter. The issue is with the ref AudioClip.

You simply can’t. ref parameters are not “normal parameters”. They can not be part of a closure. That’s why C# actually doesn’t allow ref or out parameters in coroutines / iterators since they are implicit closures. ref parameters are actual pointers to the memory location where the variable was stored. The ref semantic allows passing pointers to local variables. That’s why you can not “store” such a pointer in any variable for later use.

Your only option is to use a callback delegate when you start the coroutine. Keep in mind that coroutines are supposed to run code later in time. You can not wait for its completion synchonously. That’s the main point of coroutines. They execute code seemingly in parallel. The coroutine is actually resumed later in time. StartCoroutine will return as soon as the coroutine hits the first yield return statement. However at this point the asynchronous task you yielded has not been completed. Unity will resume the coroutine at a later point in time. However your calling code would have been completed at that point. To actually handle the result you have to off load this handling code into a callback method / lambda expression.

Your calling code snippet is not complete as it’s not clear where the variable “xSound” is declared or what you may do after the call of “changeSound”.

Do you need to contain the filename in a string before you try to pass it, rather than while you pass it?
For example something like:

        newFilename = "Weapons/guit00chug.wav";
        changeSound(ref xSound, newFilename);