Loading Transition
Animated screen-cover transitions for loading screen entry and exit
Overview
Loading Transition is the abstract base class for all screen-cover animations that play before and after a loading screen appears. Instead of a plain canvas fade, transitions let you mask the screen with effects like dot wipes, fill sweeps, or any fully custom animation.
Transitions are played at two moments in the loading lifecycle:
- Start Transition — covers the screen first, then the loading screen appears beneath it before the transition dissolves away.
- End Transition — covers the loading screen, which is then hidden instantly before the transition reveals the new scene.
Each transition runs on its own Canvas set to ScreenSpaceOverlay with a high sorting order (32700) so it always renders on top of everything else.
Setup
Transitions are assigned directly on the Loading Screen component via two prefab fields.
Create a new prefab and optionally add a Canvas component to the prefab object. If not added, it will be added automatically when you add the transition component.
Add your chosen transition component (e.g. Dot Wipe Transition or Fill Wipe Transition) to the prefab object and configure its appearance and timing in the Inspector.
Save the transition prefab, then open your loading screen prefab and assign it to Start Transition Prefab, End Transition Prefab, or both.
You can assign different prefabs to the start and end slots, for example, a dot wipe in and a horizontal fill out, or leave either field empty to fall back to the standard canvas fade.
Built-in Transitions
Two transitions are included out of the box. All settings are exposed in the Inspector and are self-explanatory. Just add the component to your prefab and tweak to taste.
| Transition | Description |
|---|---|
DotWipeTransition | A grid of dots that expand from the screen centre outward in a ripple pattern, then contract away. Supports custom shape textures, grid density, wave strength, and color. |
FillWipeTransition | A solid colour that sweeps across the screen. Supports four fill modes: Horizontal, Vertical, RadialSweep, and RadialIris, plus configurable direction and edge softness. |
If neither suits your needs, see Creating a Custom Transition below.
Creating a Custom Transition
Any class that extends LoadingTransition can be used as a transition. You only need to implement two coroutines: PlayIn and PlayOut.
Rules
PlayInmust not return until the screen is completely hidden.PlayOutmust not return until the transition is completely invisible.- The component requires a
Canvason the same GameObject.LoadingTransition.Awakeconfigures it automatically — always callbase.Awake()when overriding.
Minimal Example
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using Evo.Loader;
public sealed class FadeTransition : LoadingTransition
{
[SerializeField] private Color color = Color.black;
[SerializeField, Min(0)] private float inDuration = 0.4f;
[SerializeField, Min(0)] private float outDuration = 0.4f;
[SerializeField] private AnimationCurve curve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
RawImage overlay;
protected override void Awake()
{
base.Awake(); // Always call base — it sets up the Canvas.
// Create a full-screen overlay image.
var go = new GameObject("Fade_Overlay", typeof(RectTransform));
go.transform.SetParent(transform, false);
var rt = go.GetComponent<RectTransform>();
rt.anchorMin = Vector2.zero;
rt.anchorMax = Vector2.one;
rt.offsetMin = rt.offsetMax = Vector2.zero;
overlay = go.AddComponent<RawImage>();
overlay.color = new Color(color.r, color.g, color.b, 0f);
overlay.raycastTarget = false;
}
public override IEnumerator PlayIn()
{
// Fade the overlay from transparent to opaque.
yield return LerpFloat(0f, 1f, inDuration, SetAlpha, curve);
}
public override IEnumerator PlayOut()
{
// Fade the overlay from opaque back to transparent.
yield return LerpFloat(1f, 0f, outDuration, SetAlpha, curve);
}
void SetAlpha(float alpha)
{
overlay.color = new Color(color.r, color.g, color.b, alpha);
}
}Shader-Driven Example
For more advanced effects, drive a custom material's properties inside PlayIn / PlayOut, the same way the built-in transitions do:
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using Evo.Loader;
public sealed class ShaderTransition : LoadingTransition
{
[SerializeField] private Shader transitionShader;
[SerializeField, Min(0)] private float inDuration = 0.8f;
[SerializeField, Min(0)] private float outDuration = 0.8f;
static readonly int ID_Progress = Shader.PropertyToID("_Progress");
Material mat;
protected override void Awake()
{
base.Awake();
if (transitionShader == null)
{
Debug.LogError("[ShaderTransition] No shader assigned.", this);
return;
}
var go = new GameObject("CustomShader_Overlay", typeof(RectTransform));
go.transform.SetParent(transform, false);
var rt = go.GetComponent<RectTransform>();
rt.anchorMin = Vector2.zero;
rt.anchorMax = Vector2.one;
rt.offsetMin = rt.offsetMax = Vector2.zero;
var image = go.AddComponent<RawImage>();
image.raycastTarget = false;
mat = new Material(transitionShader);
image.material = mat;
mat.SetFloat(ID_Progress, 0f);
}
void OnDestroy()
{
if (mat != null) Destroy(mat);
}
public override IEnumerator PlayIn()
{
yield return LerpFloat(0f, 1f, inDuration, p => mat.SetFloat(ID_Progress, p));
}
public override IEnumerator PlayOut()
{
yield return LerpFloat(1f, 0f, outDuration, p => mat.SetFloat(ID_Progress, p));
}
}Always Destroy(mat) in OnDestroy when creating a new Material(...) at runtime. Instantiated materials are not automatically cleaned up by Unity.
API Reference
Abstract Members
| Member | Type | Description |
|---|---|---|
PlayIn() | IEnumerator | Animate to fully cover the screen. Must not yield until the screen is completely hidden. |
PlayOut() | IEnumerator | Animate to fully reveal the screen. Must not yield until the transition is completely invisible. |
Protected Members
| Member | Type | Description |
|---|---|---|
TransitionCanvas | Canvas | The Canvas component on this GameObject, configured automatically in Awake. |
LerpFloat(from, to, duration, onUpdate, curve) | IEnumerator | Drives a float value over unscaled time. |
LerpFloat Helper
The base class exposes a built-in coroutine for driving animated values:
protected IEnumerator LerpFloat(
float from,
float to,
float duration,
System.Action<float> onUpdate,
AnimationCurve curve = null)| Parameter | Description |
|---|---|
from | Start value. |
to | End value. |
duration | Total duration in unscaled seconds. If ≤ 0, the end value is applied immediately. |
onUpdate | Callback invoked each frame with the current interpolated value. |
curve | Optional AnimationCurve that remaps the 0–1 progress before lerping. |