Can you create transitions between levels using Application.LoadLevel?

I am using the following function to load between multiple scenes

function OnMouseDown(){
    Application.LoadLevel("Level 2");   
}

It works fine, but I was wondering if there was a way to apply transitions (motion effects) between the scenes. Right now the scene changes with a hard cut and it is a little jarring to the player.

Can you do wipes, fades, or other cut effects specifically when switching levels?

Any thoughts are appreciated. Thanks

In Unity Game Development Essentials there is an example of fading to white between the main menu and the first level. I'd imagine you can use something similar for other effects. I've amended it myself for creating a black fadeout when the player is caught by an enemy.

In the book, Will creates an empty gameObject in the first level and places the following script on it. When the first level is loaded, a white fade in plays for 3 seconds.

// store a small, repeatable texture (a white square)
var theTexture : Texture2D;
private var StartTime : float;

function OnLevelWasLoaded(){
  // Store the current time
  StartTime = Time.time;
}

function Update(){
  // if 3 seconds have passed since the timer was started
  if(Time.time-StartTime >= 3){
    // destroy the gameobject this script is attached to
    Destroy(gameObject);
  }
}

function OnGUI(){
  // set the color of the GUI
  GUI.color = Color.white;

  // interpolate the alpha of the GUI from 1(fully visible) 
  // to 0(invisible) over time
  GUI.color.a = Mathf.Lerp(1.0, 0.0, (Time.time-StartTime));

  // draw the texture to fill the screen
  GUI.DrawTexture(Rect(0,0,Screen.width, Screen.height), theTexture);

}

Scrip taken from the FPS Tutorial: http://unity3d.com/support/resources/tutorials/fpstutorial

/*
    Usage:

    // Load my level    
    LevelLoadFade.FadeAndLoadLevel("mylevel", Color.white, 0.5);

    // Reset the current level
    LevelLoadFade.FadeAndLoadLevel(Application.loadedLevel, Color.white, 0.5);
*/

static function FadeAndLoadLevel (level, fadeTexture : Texture2D, fadeLength : float)
{
    if (fadeTexture == null)
        FadeAndLoadLevel(level, Color.white, fadeLength);

    var fade = new GameObject ("Fade");
    fade.AddComponent(LevelLoadFade);
    fade.AddComponent(GUITexture);
    fade.transform.position = Vector3 (0.5, 0.5, 1000);
    fade.guiTexture.texture = fadeTexture;
    fade.GetComponent(LevelLoadFade).DoFade(level, fadeLength, false);
}

static function FadeAndLoadLevel (level, color : Color, fadeLength : float)
{
    var fadeTexture = new Texture2D (1, 1);
    fadeTexture.SetPixel(0, 0, color);
    fadeTexture.Apply();

    var fade = new GameObject ("Fade");
    fade.AddComponent(LevelLoadFade);
    fade.AddComponent(GUITexture);
    fade.transform.position = Vector3 (0.5, 0.5, 1000);
    fade.guiTexture.texture = fadeTexture;

    DontDestroyOnLoad(fadeTexture);
    fade.GetComponent(LevelLoadFade).DoFade(level, fadeLength, true);
}

function DoFade (level, fadeLength : float, destroyTexture : boolean)
{
    // Dont destroy the fade game object during level load
    DontDestroyOnLoad(gameObject);

    // Fadeout to start with
    guiTexture.color.a = 0;

    // Fade texture in
    var time = 0.0;
    while (time < fadeLength)
    {
        time += Time.deltaTime;
        guiTexture.color.a = Mathf.InverseLerp(0.0, fadeLength, time);
        yield;
    }
    guiTexture.color.a = 1;
    yield;

    // Complete the fade out (Load a level or reset player position)
    Application.LoadLevel(level);

    // Fade texture out
    time = 0.0;
    while (time < fadeLength)
    {
        time += Time.deltaTime;
        guiTexture.color.a = Mathf.InverseLerp(fadeLength, 0.0, time);
        yield;
    }
    guiTexture.color.a = 0;
    yield;

    Destroy (gameObject);

    // If we created the texture from code we used DontDestroyOnLoad,
    // which means we have to clean it up manually to avoid leaks
    if (destroyTexture)
        Destroy (guiTexture.texture);
}

Application.LoadLevel takes one frame to execute, so by definition motion effects are not possible during the load. You can make effects before or after the LoadLevel call though. Unity Pro has LoadLevelAsync, which, as you would expect from the name, is non-blocking.

I ran into a problem using the script from the FPS tutorial. The texture that is faded in and out shows UNDER the GUI elements drawn by the scenes.

Apparently all GUI elements drawn inside OnGUI methods display on top of all GUITextures. In order to display the transition texture on top of everything you have to use GUI.DrawTexture instead of the GUITexture component.

Here's a modified version of LevelLoadFade.js that uses GUI.DrawTexture.

NOTE #1: You have to set GUI.depth to something GREATER THAN the value used in this script (-100). Since depth is a static variable, you HAVE to set it back to 0 or whatever in your other OnGUI methods, or they'll all just get drawn at depth -100.

EDIT: I discovered I could use GUI.color to animate the alpha value of the texture without having to change any pixel data, so this script can do custom textures again.

/*
    Usage:

    // Load my level    
    LevelLoadFade.FadeAndLoadLevel("mylevel", Color.white, 0.5);

    // Reset the current level
    LevelLoadFade.FadeAndLoadLevel(Application.loadedLevel, Color.white, 0.5);
*/
static function FadeAndLoadLevel(level, fadeTexture:Texture2D, fadeLength:float) {
    if(fadeTexture == null)
        FadeAndLoadLevel(level, Color.white, fadeLength);

    var fade = new GameObject ("Fade");
    fade.AddComponent(LevelLoadFade);
    fade.GetComponent(LevelLoadFade).DoFade(level, fadeLength, fadeTexture, Color.white, false);
}

static function FadeAndLoadLevel(level, color:Color, fadeLength:float) {
    color.a = 1; // Make sure the texture is opaque so it will actually cover the scene
    var fadeTexture = new Texture2D (1, 1);
    fadeTexture.SetPixel(0, 0, color);
    fadeTexture.Apply();
    DontDestroyOnLoad(fadeTexture);

    var fade = new GameObject ("Fade");
    fade.AddComponent(LevelLoadFade);
    fade.GetComponent(LevelLoadFade).DoFade(level, fadeLength, fadeTexture, color, true);
}

private var _fadeTexture:Texture2D;
private var _rect:Rect;
private var _color:Color;

function Awake():void {
    _rect = new Rect(0, 0, Screen.width, Screen.height);
    _fadeTexture = null;
}

function OnGUI():void {
    if(_fadeTexture != null) {
        GUI.depth = -100; // Lower depth values display on TOP of higher ones
        GUI.color = _color;
        GUI.DrawTexture(_rect, _fadeTexture);
    }
}

function DoFade(level, fadeLength:float, fadeTexture:Texture2D, color:Color, destroyTexture:boolean) {
    transform.position = Vector3.zero;
    // Dont destroy the fade game object during level load
    DontDestroyOnLoad(gameObject);

    // Fadeout to start with
    _color = color;
    _color.a = 0;
    _fadeTexture = fadeTexture;

    // Fade texture in
    var time = 0.0;
    while(time < fadeLength) {
        time += Time.deltaTime;
        _color.a = Mathf.InverseLerp(0, 1, time / fadeLength);
        yield;
    }
    _color.a = 1;
    yield;

    // Complete the fade out (Load a level or reset player position)
    Application.LoadLevel(level);

    // Fade texture out
    time = 0.0;
    while(time < fadeLength) {
        time += Time.deltaTime;
        _color.a = Mathf.InverseLerp(1, 0, time / fadeLength);
        yield;
    }
    _color.a = 0;
    yield;

    _fadeTexture = null;
    Destroy(gameObject);
    if(destroyTexture)
        Destroy(fadeTexture);
}

Very simple and easy to use Transitions between changing scenes - Questions & Answers - Unity Discussions

Tornado Twins just released a Transition Pack on UnityPrefabs.com. It is compatible with Unity 2.6 and 3.X