I am using a coroutine in such a way where I need to know the value of a variable inside of the coroutine from an Update loop. Coroutines say that I cannot use Out or Ref variables in declarations. And I can’t figure out how to get a coroutine to return it’s value. I assume none of those things can be done.
I have the coroutine working the way I want it to by having the coroutine modify a global variable, but I really need to take advantage of the fact the coroutine is instanced on call. Meaning, I am going to be calling this coroutine multiple times in an update, and each instance of the coroutine is going to be modifying a different global variable. And I can’t figure out how to get that to work, because if I pass my global variable into the coroutine through the coroutine call, the global variable gets instanced, and the actual global doesn’t get modified by the coroutine.
How can I make it so that I can call a coroutine and have the coroutine modify different global variables based on how I call the coroutine?
Like Peter G mentioned in his comment you best bet is to use a callback, here’s an example:
using UnityEngine;
using System;
using System.Collections;
public class CoroutineTest : MonoBehaviour {
public Rect rect;
public void setRect(Rect newRect){
rect = newRect;
}
private IEnumerator leCoroutine(Action<Rect> rectCallback){
Rect newRect = new Rect();
//calculate new rect
rectCallback(newRect);
yield return null;
}
void Start(){
StartCoroutine(leCoroutine(setRect));
}
}
You could put your rects in a container class that is passed by reference:
[System.Serializable]
class Container {
public Rect rectPassedByRef;
}
public class CoroutineTest : MonoBehaviour {
public Container myContainer;
public void Start () {
Debug.Log(myContainer.rectPassedByRef);
//prints 0 , 0 , 0 , 0
StartCoroutine ( MyCoroutine(myContainer) );
Debug.Log(myContainer.rectPassedByRef);
//prints 10 , 10 , 5 , 5
}
public IEnumerator MyCoroutine (Container HoldingObj) {
while ( someCondition ) { //The point is that it loops for while.
HoldingObj.rectPassedByRef = new Rect( 10 , 10 , 5 , 5 );
//Container will be passed by reference.
yield return null;
}
}
}
It isn’t the most elegant solution, but it should work. According to MSDN though:
When
you pass a reference-type parameter by
value, it is possible to change the
data pointed to by the reference, such
as the value of a class member.
However, you cannot change the value
of the reference itself;
You are probably familiar with this, but its worth noting. Assuming my interpretation is correct, the reference is instanced. So you can still affect the edit object because the original variable and the local variable will be pointing toward the same object. But if you change what you are pointing at (There are plenty of ways to do this assigning it to a different reference or creating a new instance), then the original reference will not point at anything else. This is called passing a reference by value.