How to pass reference to variable in IEnumerator method in C#?

using UnityEngine;
using System.Collections;

public class myTimer : MonoBehaviour {
	
	public int myInt1;
	public int myInt2;
	public int myInt3;
	
	void Start() 
	{
		
		StartCoroutine(ValueFader(0f, 100f, 5f, myInt1));
		StartCoroutine(ValueFader(0f, 180f, 5f, myInt2));
		StartCoroutine(ValueFader(0f, 115f, 5f, myInt3));

	}
	
	void Update()
	{
	
		//...
		
	}
	
	public IEnumerator ValueFader(float myStartValue, float myEndValue, float myDuration, out int myValue)
	{
	
		float myStartTime = Time.time;
		
		while (Time.time < myStartTime + myDuration)
		{
		
			myValue = (int)(myStartValue + ((myEndValue - myStartValue) * ((Time.time - myStartTime) / myDuration)));
			
			yield return null;
			
		}
		
		myValue = myEndValue;
		
	}
	
	void OnGUI()
	{
	
		GUI.Label(new Rect(0, 0, 80, 20), "myValue: " + myInt1);
		GUI.Label(new Rect(0, 20, 80, 20), "myValue: " + myInt2);
		GUI.Label(new Rect(0, 40, 80, 20), "myValue: " + myInt3);
		
	}
	
}

Unity tells me: Error CS1623: Iterators cannot have ref or out parameters

What I want to do, is to be able to input/reference a specific variabel, whose value will be changed, from myStartValue to myEndValue, over time = myDuration.

Why doesn’t it work? Can it be made to work? If not, how can I do this in a different way? I don’t want to depend on Update(), preferably.

Thank you for your time! :]

Instead of passing ref/out parameters, you can pass Action:

public IEnumerator ValueFader(float myStartValue, float myEndValue, float myDuration, System.Action<int> action)

and then call the action every time the value changes:

action(myValue);

Of course in this case you have to declare myValue inside of method, because it is no longer a parameter.

You can call changed coroutine passing lambda expression as action. For example:

StartCoroutine(ValueFader(0f, 100f, 5f, (x) => myInt1 = x));

Here’s a convenient full example of that:

private float stars; // it could even be a Property

private IEnumerator _transition(string letterCode)
 {
 yield return StartCoroutine(
    Tween((x)=>stars=x, 3f,300f, 1f) );
 yield return new WaitForSeconds(1f);
 yield return StartCoroutine(
    Tween((x)=>stars=x, 300f,3f, 1f) );
 }

private IEnumerator Tween( System.Action<float> var,
      float aa, float zz, float duration )
 {
 float sT = Time.time;
 float eT = sT + duration;

 while (Time.time < eT)
  {
  float t = (Time.time-sT)/duration;
  var( Mathf.SmoothStep(aa,zz, t) );
  yield return null;
  }

 var(zz);
 }

Hope it saves some typing.

Well a different way of doing it would be to store the ints in an int then passing in the index, and setting that index in the coroutine like this

using UnityEngine;
using System.Collections;

public class TestScript : MonoBehaviour
{
    public int[] myInts;

    void Start()
    {
        myInts = new int[3];
        StartCoroutine(ValueFader(0f, 100f, 5f, 0));
        StartCoroutine(ValueFader(0f, 180f, 5f, 1));
        StartCoroutine(ValueFader(0f, 115f, 5f, 2));
    }
    void Update()
    {
        //...
    }

    public IEnumerator ValueFader(float myStartValue, float myEndValue, float myDuration, int myIndex)
    {
        float myStartTime = Time.time;
        while (Time.time < myStartTime + myDuration)
        {
            myInts[myIndex] = (int)(myStartValue + ((myEndValue - myStartValue) * ((Time.time - myStartTime) / myDuration)));
            yield return null;
        }
        myInts[myIndex] = (int)myEndValue;
    }

    void OnGUI()
    {
        GUI.Label(new Rect(0, 0, 80, 20), "myValue: " + myInts[0]);
        GUI.Label(new Rect(0, 20, 80, 20), "myValue: " + myInts[1]);
        GUI.Label(new Rect(0, 40, 80, 20), "myValue: " + myInts[2]);
    }

}