My coroutine fader is not fading

I made a script to fade a scene to black starting from some examples, I tried to do it with coroutines rather than just doing it in update, with the hope that the fader would actually stop the calling object until it’s done with the fading animation.

I also tried to dynamically generate the texture rather than making a big black texture manually.

In my controller, just before loading the new scene, I call

var fader = GameObject.FindObjectOfType<SceneFadeInOut>();
            fader.StartFade();

here’s the fader class

public class SceneFadeInOut : MonoBehaviour
    {
        private Texture2D _blackTexture;

        public float FadeSpeed = 1.5f;
        private bool _doFade = false;
        private GUITexture _GUITexture;

        public Color FadeTo; 
        public Color FadeFrom;
            



        private void Awake()
        {
            _blackTexture = new Texture2D(1,1);
            _blackTexture.SetPixel(0,0,Color.black);
            

            _GUITexture = GetComponent<GUITexture>();
            _GUITexture.texture = _blackTexture;
            _GUITexture.pixelInset = new Rect(0,0,Screen.width,Screen.height);


        }

        public void StartFade()
        {
            StartCoroutine(Fade(_GUITexture, FadeSpeed, FadeFrom, FadeTo));
        }

        IEnumerator Fade(GUITexture mat, float duration, Color startColor, Color endColor)
        {  // remember the start
            float start = Time.time;
            float elapsed = 0;
            do
            {  // calculate how far through we are
                elapsed = Time.time - start;
                float normalisedTime = Mathf.Clamp(elapsed / duration, 0, 1);
                mat.color = Color.Lerp(startColor, endColor, normalisedTime);
                // wait for the next frame
                yield return null;
            }
            while (elapsed > duration);
        }

    }

When I do the transition the coroutine code seems to run but nothing really happens and then the new scene loads as normal

What could I be doing wrong?

I finally managed to find the solution so here’s what I did:

First I scrapped the GUITexture and instead I made a RawImage and put it inside a canvas, then I attached the script to it.
The RawImage doesn’t need to have a texture set, just the color (to black).

Then the script is as follows:

public class SceneFadeInOut : MonoBehaviour
    {   
        private RawImage _image; 

        private void Awake()
        {

            _image = GetComponent<RawImage>();  
        }
   
        public IEnumerator FadeIn(float speed)
        {
            yield return StartCoroutine(Fade(_image, speed, Color.black, Color.clear));
        }

        public IEnumerator FadeOut(float speed)
        {
            yield return StartCoroutine(Fade(_image, speed, Color.clear, Color.black));
        }

        IEnumerator Fade(RawImage mat, float duration, Color startColor, Color endColor)
        {  
            float start = Time.time;
            float elapsed = 0;
             while (elapsed < duration) { 
              // calculate how far through we are
                elapsed = Time.time - start;
                float normalisedTime = Mathf.Clamp(elapsed / duration, 0, 1);
                mat.color = Color.Lerp(startColor, endColor, normalisedTime);
                // wait for the next frame
                yield return null; 
            }              
        }  
    }

And that’s it, it just works, just call startcoroutine with fadein or fadeout and everything works neatly!

A little late to the party, but here’s my contribution. I use a ui Panel instead of a 2D Texture

using UnityEngine;
using System.Collections;

public class FadePanel : MonoBehaviour
{
	// Add a fade panel to your UI Canvas
	// Make the panel black (On image component, 
	// set image to none, make color black)
	// Add a Canvas Group component to the panel
	// Set the Alpha of the canvas group to 0
	// Add this script to the panel 

	public CanvasGroup canvasGroup;     // Drop the panel with the canvas 
										// group on this field in the inspector
										// or make it private and use GetComponent 
										// in Awake()
	public float fadeSpeed = 1f;

	void Start()				// If you want the panel to fade in when the scene loads
	{
		StartCoroutine("Fade");
	}

	public void FadePanelIn()	// If you want to fade to black at some other time
	{
		StartCoroutine("Fade");
	}

	IEnumerator Fade()
	{
		while (canvasGroup.alpha != 1)
		{
			canvasGroup.alpha = Mathf.MoveTowards(canvasGroup.alpha, 1, fadeSpeed * Time.deltaTime);
			yield return null;
		}
	}
}

this in incorrect , the script does not run continuously due to the while being in the wrong place it should be like so

  IEnumerator Fade(GUITexture mat, float duration, Color startColor, Color endColor)
                 {while (elapsed > duration){
         // remember the start
                     float start = Time.time;
                     float elapsed = 0;
       
                     
// calculate how far through we are
                         elapsed = Time.time - start;
                         float normalisedTime = Mathf.Clamp(elapsed / duration, 0, 1);
                         mat.color = Color.Lerp(startColor, endColor, normalisedTime);
                         // wait for the next frame
                       //  yield return null; incorrect will stop coroutine
                      yield return new WaitForEndOfFrame();
                     }
                     
                 }