I have 2 IEnumerator coroutines that are similar enough that they should be combined:
A:
IEnumerator CountDown_A() {
timeLeft_A = totalTime_A;
while (timeLeft_A > 0) {
yield return new WaitForSeconds(1);
timeLeft_A--;
}
}
B:
IEnumerator CountDown_B() {
timeLeft_B = totalTime_B;
while (timeLeft_B > 0) {
yield return new WaitForSeconds(1);
timeLeft_B--;
}
}
The only 2 differences are the variables totalTime_A
vs totalTime_B
and timeLeft_A
vs timeLeft_B
. These vars are from outside the scope of this function.
The problem I'm having modularizing this coroutine is that the incremented value of timeLeft_A
and timeLeft_B
needs to apply outside this function, so I need to pass a reference to them somehow.
User "Kurt-Dekker" posted a great solution in this thread but I'm having trouble applying it to my code. He says to "use a closure (functor) to allow the coroutine to modify it by callback":
IEnumerator CountDown( System.Action<int> callback){
....
}
which I think would be called like so:
StartCoroutine ( CountDown( (i) => { timeLeft_A = i; } ) );
StartCoroutine ( CountDown( (i) => { timeLeft_B = i; } ) );
What I don't understand is how to then reference/modify the actual value of the int being passed in, inside the IEnumerator, if all I have to work with is a callback function. For example to do the following:
while(callback > 0){
or:
callback--;
Any help appreciated.
I think this may answer your question, on how to use the System.Action<float>
within a coroutine.
Basicaly, when you call StartCoroutine
you give the maximum time for you counter as a normal parameter and a callback, this callback takes a float as argument (here it is i).
If you call callback(--timeLeft);
in your coroutine, it will execute the System.Action
you passed in.
Here it will set the timeLeft_A
or timeLeft_B
to the timeLeft
variable of the corresponding coroutine.
public float timeLeft_A = 0f;
public float timeLeft_B = 0f;
public float totalTime_A = 15f;
public float totalTime_B = 20f;
// Start is called before the first frame update
void Start()
{
StartCoroutine(Cooldown(totalTime_A, (i) =>
{
timeLeft_A = i;
}));
StartCoroutine(Cooldown(totalTime_B, (i) =>
{
timeLeft_B = i;
}));
}
IEnumerator Cooldown(float totalTime, Action<float> callback)
{
var timeLeft = totalTime;
while (timeLeft > 0)
{
yield return new WaitForSeconds(1);
callback(--timeLeft);
}
}