0
\$\begingroup\$

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;

    }
}
    
\$\endgroup\$
2
\$\begingroup\$

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 < 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 < 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.

\$\endgroup\$
4
  • \$\begingroup\$ Thank you for taking an extra step to point out my other mistakes. Unfortunately it still doesn't proceed to the next coroutine. It just stays black. Also making the originalColor variable as a reference to night.color seems to just make it not work altogether \$\endgroup\$ Apr 11 at 23:29
  • \$\begingroup\$ Have you fixed your second coroutine following the model of the first? \$\endgroup\$
    – DMGregory
    Apr 11 at 23:30
  • \$\begingroup\$ Yes, I did fixed it. \$\endgroup\$ Apr 11 at 23:32
  • \$\begingroup\$ Thank you. The combined code works. Will keep in mind to avoid redundant code from now on \$\endgroup\$ Apr 12 at 2:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.