Greetings,
I am trying to nest Coroutines. It seems to work OK, except that the last nested coroutine exits early.
In a nutshell, here’s what I’m trying to do (in pseudocode)
// start coroutine "add to scene"
// start coroutine "fade to black", yield
// does some simple logic
// start coroutine "fade in from black", yield
As you can see, I want my “add to scene” Coroutine
to be “wrapped” in the complete execution of two other Coroutine
s, fading a Unity.UI
Panel
in and out (using Color.Lerp
and adjusting the alpha channel of the start color to determine the end color).
The first Coroutine
“fade to black” works totally fine; it fades out as expected. Then, the simple logic is performed, as expected.
However, the final Coroutine
“fade in from black” seems to yield only one time, even though I am using the same type of yield return
statement on it.
What am I doing wrong here?
Here’s some mildly redacted example code:
private IEnumerator TransitionToScene(string sceneName) {
Debug.Log("Transitioning. Starting fade out...");
//Start a fade-out
yield return StartCoroutine(Fade(FadeStyle.FadeOut));
// OTHER STUFF IN HERE
Debug.Log("Loaded! Fading in, now...");
//Start a fade-in
yield return StartCoroutine(Fade(FadeStyle.FadeIn));
Debug.Log("Fade in complete");
}
Here’s the actual “Fade” Coroutine, also:
//Create a Coroutine which will fade in or out
private IEnumerator Fade( FadeStyle style, float fadeTime = .25f ) {
//Early exit for invalid fade style
if(style == FadeStyle.Invalid) { Debug.Log("INVALID FADE: Early-exit."); yield break; }
Debug.Log("Fade coroutine started...");
//Keep track of our fade progress out here for the coroutine...
float fadeProgress = 0;
//Grab the start color
Color start = fadeImage.color;
//Create a target color based on the start color...
Color end = start;
//If we're fading in, the target alpha is 0. If we're fading out, it's 1.
end.a = style == FadeStyle.FadeIn ? 0 : 1;
Debug.Log("Fading from " + start + " to " + end);
//While we have not faded, yet...
while(fadeProgress < fadeTime) {
string inOrOut = style == FadeStyle.FadeIn ? "In" : "Out";
Debug.Log("Fade " + inOrOut + ": " + fadeProgress + " / " + fadeTime);
//Calculate how far along we should be in the color transitions...
float lerpVal = fadeProgress / fadeTime;
Color newColor = Color.Lerp(start, end, lerpVal);
//Apply it
fadeImage.color = newColor;
//Increment time
fadeProgress += Time.deltaTime;
//Continue next frame
yield return null;
}
Debug.Log("Fade coroutine complete... (" + fadeProgress + " / " + fadeTime + ")");
}
And, finally, some debug output:
Fade coroutine started...
UnityEngine.Debug:Log(Object)
<Fade>c__Iterator0:MoveNext() (at Assets/SceneManager.cs:75)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
<TransitionToScene>c__Iterator1:MoveNext() (at Assets/SceneManager.cs:160)
Fading from RGBA(0.000, 0.000, 0.000, 0.998) to RGBA(0.000, 0.000, 0.000, 0.000)
UnityEngine.Debug:Log(Object)
<Fade>c__Iterator0:MoveNext() (at Assets/SceneManager.cs:87)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
<TransitionToScene>c__Iterator1:MoveNext() (at Assets/SceneManager.cs:160)
Fade In: 0 / 0.25
UnityEngine.Debug:Log(Object)
<Fade>c__Iterator0:MoveNext() (at Assets/SceneManager.cs:93)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
<TransitionToScene>c__Iterator1:MoveNext() (at Assets/SceneManager.cs:160)
Fade In: 0.001157403 / 0.25
UnityEngine.Debug:Log(Object)
<Fade>c__Iterator0:MoveNext() (at Assets/SceneManager.cs:93)
Fade In: 0.008806617 / 0.25
UnityEngine.Debug:Log(Object)
<Fade>c__Iterator0:MoveNext() (at Assets/SceneManager.cs:93)
Fade coroutine complete... (0.2785531 / 0.25)
UnityEngine.Debug:Log(Object)
<Fade>c__Iterator0:MoveNext() (at Assets/SceneManager.cs:109)