0

I have a method that fades the screen to black, then fades away back again using coroutines but I couldn't get the 2nd part to work.

FadeToBlack() works if I put yield return null instead of yield return StartCoroutine(LightUp()); so I know that isn't the problem

 private IEnumerator FadeToBlack()
{
for (float t = 0.01f; t < fadeOutTime; t += Time.deltaTime)
{

    color = new Color(0, 0, 0, 1);
    night.color = Color.Lerp(night.color, color, Mathf.Min(1, t / fadeOutTime));            
    yield return StartCoroutine(LightUp());

}}

If I put yield return StartCoroutine(LightUp()); in FadeToBlack instead of null it immediately turns black without the fading part. Here's what LightUp(); looks like

private IEnumerator LightUp() {
    for (float t = 0.01f; t < fadeOutTime; t += Time.deltaTime)
    {
        color = new Color(0, 0, 0, 0);
      Color colorD = new Color(0, 0, 0, 1);
        night.color = Color.Lerp(colorD, color, Mathf.Min(1, t / fadeOutTime));
    yield return null;

}

}

1 Answers1

2

You want to start your fade back to light coroutine after your fade to black loop has finished all of its work, not once in every iteration of the loop (ie. every frame the black fade is supposed to be updating).

Move it outside the loop like so:

private IEnumerator FadeToBlack()
{
    Color originalColor = night.color;
for (float t = 0.01f; t &lt; fadeOutTime; t += Time.deltaTime)
{            
    night.color = Color.Lerp(originalColor, Color.black, t / fadeOutTime);            
    yield return null;        
}

yield return StartCoroutine(LightUp());

}

I also corrected your lerp, which included a common error that makes the time adjustment incorrect.

We can even combine FadeToBlack and LightUp into one to remove the redundant code, then just call the coroutine twice:

public class FadeTest : MonoBehaviour
{
    public Image night;
    public float fadeOutTime = 1f;
// Start is called before the first frame update
void Start()
{
    StartCoroutine(FadeThroughBlack());
}


private IEnumerator FadeThroughBlack() {
    yield return FadeTo(Color.black);
    yield return FadeTo(Color.clear);
}

private IEnumerator FadeTo(Color destination) {
    Color originalColor = night.color;

    for (float t = 0.01f; t &lt; fadeOutTime; t += Time.deltaTime) {            
        night.color = Color.Lerp(originalColor, destination, t / fadeOutTime);
        yield return null;
    }

    night.color = destination;
}

}

I've tested this and verified that it correctly fades the image to black, then fades it to transparent. If you don't observe this then you should edit your question to include a minimal complete verifiable example of the problem you're seeing.

DMGregory
  • 134,153
  • 22
  • 242
  • 357