Transitions between changing scenes

hey guys,

Is it possible to make transitions when changing scenes. So like it might fade out, or zoom out or whatever…

thanks :slight_smile:

-Grady

I’ve written a “small” script that allows you to load a level, but it fades the old level out and fades the new one in. The documentation states that the GL class is only available in Unity pro, but in my Unity version (3.0) it works fine in the free version :wink:

// AutoFade.cs
using UnityEngine;
using System.Collections;

public class AutoFade : MonoBehaviour
{
    private static AutoFade m_Instance = null;
    private Material m_Material = null;
    private string m_LevelName = "";
    private int m_LevelIndex = 0;
    private bool m_Fading = false;

    private static AutoFade Instance
    {
        get
        {
            if (m_Instance == null)
            {
                m_Instance = (new GameObject("AutoFade")).AddComponent<AutoFade>();
            }
            return m_Instance;
        }
    }
    public static bool Fading
    {
        get { return Instance.m_Fading; }
    }

    private void Awake()
    {
        DontDestroyOnLoad(this);
        m_Instance = this;
        m_Material = new Material("Shader \"Plane/No zTest\" { SubShader { Pass { Blend SrcAlpha OneMinusSrcAlpha ZWrite Off Cull Off Fog { Mode Off } BindChannels { Bind \"Color\",color } } } }");
    }

    private void DrawQuad(Color aColor,float aAlpha)
    {
        aColor.a = aAlpha;
        m_Material.SetPass(0);
        GL.PushMatrix();
        GL.LoadOrtho();
        GL.Begin(GL.QUADS);
        GL.Color(aColor);   // moved here, needs to be inside begin/end
        GL.Vertex3(0, 0, -1);
        GL.Vertex3(0, 1, -1);
        GL.Vertex3(1, 1, -1);
        GL.Vertex3(1, 0, -1);
        GL.End();
        GL.PopMatrix();
    }

    private IEnumerator Fade(float aFadeOutTime, float aFadeInTime, Color aColor)
    {
        float t = 0.0f;
        while (t<1.0f)
        {
            yield return new WaitForEndOfFrame();
            t = Mathf.Clamp01(t + Time.deltaTime / aFadeOutTime);
            DrawQuad(aColor,t);
        }
        if (m_LevelName != "")
            Application.LoadLevel(m_LevelName);
        else
            Application.LoadLevel(m_LevelIndex);
        while (t>0.0f)
        {
            yield return new WaitForEndOfFrame();
            t = Mathf.Clamp01(t - Time.deltaTime / aFadeInTime);
            DrawQuad(aColor,t);
        }
        m_Fading = false;
    }
    private void StartFade(float aFadeOutTime, float aFadeInTime, Color aColor)
    {
        m_Fading = true;
        StartCoroutine(Fade(aFadeOutTime, aFadeInTime, aColor));
    }

    public static void LoadLevel(string aLevelName,float aFadeOutTime, float aFadeInTime, Color aColor)
    {
        if (Fading) return;
        Instance.m_LevelName = aLevelName;
        Instance.StartFade(aFadeOutTime, aFadeInTime, aColor);
    }
    public static void LoadLevel(int aLevelIndex,float aFadeOutTime, float aFadeInTime, Color aColor)
    {
        if (Fading) return;
        Instance.m_LevelName = "";
        Instance.m_LevelIndex = aLevelIndex;
        Instance.StartFade(aFadeOutTime, aFadeInTime, aColor);
    }
}

You don’t need to do anything with this script, just place it somewhere in your project. It creates automatically a GameObject when you use the LoadLevel function.

To load a new level just write in any of your scripts:

AutoFade.LoadLevel(1 ,3,1,Color.black);
// or
AutoFade.LoadLevel("MyLevelName" ,3,1,Color.black);

The 4 parameters are:

  1. LevelName or LevelIndex
  2. FadeOutTime - time in seconds until the level actually starts loading
  3. FadeInTime - time in seconds until the fade-in process is completed.
  4. FadeColor - this is the color the screen fades to.

Keep in mind that after calling AutoFade.LoadLevel the game continues “FadeOutTime” seconds. You might want to block Input or something while the fade-process is active. Just check if AutoFade.Fading is true.

Have fun :wink:

edit here’s my test project (webplayer required) where you can see the script in action. I’ve posted the link already in a comment below, but just in case you can’t find it.

second edit
Since Time.deltaTime returns 0 when Time.timeScale is set to 0, it won’t fade since the t value doesn’t change. You can replace Time.deltaTime with Time.unscaledDeltaTime. That way it will work even when your game is paused. However this has one problem. Since unscaledDeltaTime is not modified / scaled / clamped, if the loading of the new level takes some time, unscaledDeltaTime might return huge values (well the time since the last frame which could even be seconds when using LoadLevel).

Time.deltaTime solves this problem by clamping the value to “Maximum Allowed Timestep”. So if a frame takes longer than that it will be clamped to that value. You would have to do that manually. an alternative would be to just skip the first frame after the level load:

//[ ... ]
    Application.LoadLevel(m_LevelIndex);
yield return null; // skip first frame in new level
while (t>0.0f)
//[ ... ]

However there might be other reasons why the unscaledDeltaTime going wrong so clamping it like Time.deltaTime is probably the best solution:

float unscaledClampedDT()
{
    return Mathf.Clamp(Time.unscaledDeltaTime ,0.00001f, Time.maximumDeltaTime);
}

You might want to clamp it to a smaller value than maximumDeltaTime. maximumDeltaTime is usually 0.33333 (1/3) so it will skip into the fading by 1/3 of a second if the loading took more than that. It’s probably the best to use both, the clampedDeltaTime and the yield to skip the first frame.

The changes would look like this:

        //[...]
        while (t<1.0f)
        {
            yield return new WaitForEndOfFrame();
            t = Mathf.Clamp01(t + unscaledClampedDT() / aFadeOutTime);
            DrawQuad(aColor,t);
        }
        if (m_LevelName != "")
            Application.LoadLevel(m_LevelName);
        else
            Application.LoadLevel(m_LevelIndex);
        yield return null; // skip first frame
        while (t>0.0f)
        {
            yield return new WaitForEndOfFrame();
            t = Mathf.Clamp01(t - unscaledClampedDT() / aFadeInTime);
            DrawQuad(aColor,t);
        }
        //[...]

Any idea how to implement AutoFade to Scene Management in Unity?

ok so the new version 4.3.4 seems that has killed the GL class on unity free…is there any alternatives to fading in and out of a scene ?

I made easiest method of AutoFade in unity by Unity Game engine, UI elemets etc…
You can free download it here… Fully explained and showed.
Enjoy and thanks, if any opinions, just write.
[54338-autofadealternative.zip|54338]

Hey guys! for those having problems with material errors, i’ve updated the script which uses GUItexture instead of material. also i used scene management to avoid conflicts.
Thank you @Bunny83 for making this, I’ve been using this code for almost 2 years now, and just decided to fix some little errors, cheers! :slight_smile:

// AutoFade.cs by Bunny83, updated unity 5 version by leztusi

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

public class AutoFade : MonoBehaviour
{
	private static AutoFade m_Instance = null;
	private string m_LevelName = "";
	private int m_LevelIndex = 0;
	private bool m_Fading = false;
	
	private static AutoFade Instance
	{
		get
		{
			if (m_Instance == null)
			{
				m_Instance = (new GameObject("AutoFade")).AddComponent<AutoFade>();
			}
			return m_Instance;
		}
	}
	public static bool Fading
	{
		get { return Instance.m_Fading; }
	}
	
	private void Awake()
	{
		DontDestroyOnLoad(this);
		m_Instance = this;
	}
	
	private void DrawQuad(Color aColor,float aAlpha)
	{
		if (!m_Instance.gameObject.GetComponent<GUITexture> ()) {
			m_Instance.gameObject.AddComponent<GUITexture> ();
		}
		m_Instance.gameObject.transform.localScale = Vector3.zero;
		Texture2D tex2d = new Texture2D(1, 1);
		tex2d.SetPixels(new Color[1] {Color.white});
		tex2d.Apply();
		m_Instance.gameObject.GetComponent<GUITexture>().texture = tex2d;

		m_Instance.GetComponent<GUITexture>().pixelInset = new Rect(0,0,Screen.width,Screen.height);
		m_Instance.GetComponent<GUITexture> ().color = new Color (aColor.r, aColor.g, aColor.b, aAlpha);
	}
	
	private IEnumerator Fade(float aFadeOutTime, float aFadeInTime, Color aColor)
	{
		float t = 0.0f;
		while (t<1.0f)
		{
			yield return new WaitForEndOfFrame();
			t = Mathf.Clamp01(t + Time.deltaTime / aFadeOutTime);
			DrawQuad(aColor,t);
		}
		if (m_LevelName != "")
			SceneManager.LoadScene(m_LevelName);
		else
			SceneManager.LoadScene(m_LevelIndex);
		while (t>0.0f)
		{
			yield return new WaitForEndOfFrame();
			t = Mathf.Clamp01(t - Time.deltaTime / aFadeInTime);
			DrawQuad(aColor,t);
		}
		m_Fading = false;
	}
	private void StartFade(float aFadeOutTime, float aFadeInTime, Color aColor)
	{
		m_Fading = true;
		StartCoroutine(Fade(aFadeOutTime, aFadeInTime, aColor));
	}
	
	public static void LoadScene(string aLevelName,float aFadeOutTime, float aFadeInTime, Color aColor)
	{
		if (Fading) return;
		Instance.m_LevelName = aLevelName;
		Instance.StartFade(aFadeOutTime, aFadeInTime, aColor);
	}
	public static void LoadScene(int aLevelIndex,float aFadeOutTime, float aFadeInTime, Color aColor)
	{
		if (Fading) return;
		Instance.m_LevelName = "";
		Instance.m_LevelIndex = aLevelIndex;
		Instance.StartFade(aFadeOutTime, aFadeInTime, aColor);
	}
}

http://www.tildee.com/0kCzlg&m=1

http://www.google.com/search?client=opera&rls=en&q=transitions+unity3d&sourceid=opera&ie=utf-8&oe=utf-8&channel=suggest

Have fun! =)