Skip to content

Instantly share code, notes, and snippets.

@GEMISIS
Last active October 7, 2020 23:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GEMISIS/b4f6a03c6fc177a1cac46b31a8e6ef3c to your computer and use it in GitHub Desktop.
Save GEMISIS/b4f6a03c6fc177a1cac46b31a8e6ef3c to your computer and use it in GitHub Desktop.
Updated Screen Fading with URP support. Yanked raw from a project, so may need further modifications later. As a result, no guarantees on this working properly.
using UnityEngine;
using UnityEngine.Rendering;
using System.Collections;
/// <summary>
/// An enumerator used to describe the type of fade
/// that was done for a fade event.
/// </summary>
public enum FadeType
{
In, Out
}
/// <summary>
/// The event handler for when the screen fade changes.
/// Called once the screen is fully faded in or out.
/// </summary>
/// <param name="sender">The camera game object calling the fade event.</param>
/// <param name="fadeType">The type of fading the occured (In or Out)</param>
public delegate void FadeChangeHandler(object sender, FadeType fadeType);
/// <summary>
/// Fades the screen from black after a new scene is loaded.
/// </summary>
public class ScreenFade : MonoBehaviour
{
/// <summary>
/// How long it takes to fade.
/// </summary>
public float FadeTime = 2.0f;
/// <summary>
/// The initial screen color, with the alpha being the fully faded in alpha value.
/// </summary>
public Color FadeInColor = new Color(0.01f, 0.01f, 0.01f, 1.0f);
/// <summary>
/// The ending screen color, but the alpha is the starting color.
/// </summary>
public Color FadeOutColor = new Color(0.01f, 0.01f, 0.01f, 0.0f);
/// <summary>
/// The delay the start of the fade in seconds.
/// </summary>
public float DelayStartTime = 0.0f;
/// <summary>
/// Internal tracker for how much time has passed since this component was enabled.
/// </summary>
private float fadeTime = 0.0f;
/// <summary>
/// The material being used for fading.
/// </summary>
public Material fadeMaterial = null;
private MeshRenderer fadeRenderer;
private MeshFilter fadeMesh;
/// <summary>
/// True when the screen is being faded currently, false otherwise.
/// </summary>
private bool isFading = true;
/// <summary>
/// True when the screen is actively being faded, false otherwise.
/// </summary>
private bool isActiveFading = false;
/// <summary>
/// The fade instruction that tells the co-routine to wait until end of frame.
/// </summary>
private readonly YieldInstruction fadeInstruction = new WaitForEndOfFrame();
/// <summary>
/// A boolean indicating whether the screen is fading currently.
/// </summary>
public bool Fading
{
get
{
return isFading;
}
}
/// <summary>
/// The event called when fading has changed.
/// </summary>
public event FadeChangeHandler FadeChanged;
private static bool attachedLWRPRendering;
/// <summary>
/// Initialize.
/// </summary>
void Awake()
{
fadeMesh = gameObject.AddComponent<MeshFilter>();
fadeRenderer = gameObject.AddComponent<MeshRenderer>();
fadeRenderer.shadowCastingMode = ShadowCastingMode.Off;
var mesh = new Mesh();
fadeMesh.mesh = mesh;
Vector3[] vertices = new Vector3[4];
float width = 2f;
float height = 2f;
float depth = 0.1001f;
vertices[0] = new Vector3(-width, -height, depth);
vertices[1] = new Vector3(width, -height, depth);
vertices[2] = new Vector3(-width, height, depth);
vertices[3] = new Vector3(width, height, depth);
mesh.vertices = vertices;
int[] tri = new int[6];
tri[0] = 0;
tri[1] = 2;
tri[2] = 1;
tri[3] = 2;
tri[4] = 3;
tri[5] = 1;
mesh.triangles = tri;
Vector3[] normals = new Vector3[4];
normals[0] = -Vector3.forward;
normals[1] = -Vector3.forward;
normals[2] = -Vector3.forward;
normals[3] = -Vector3.forward;
mesh.normals = normals;
Vector2[] uv = new Vector2[4];
uv[0] = new Vector2(0, 0);
uv[1] = new Vector2(1, 0);
uv[2] = new Vector2(0, 1);
uv[3] = new Vector2(1, 1);
mesh.uv = uv;
updateFadeMaterial(FadeInColor);
}
/// <summary>
/// Adds a <seealso cref="FadeChangeHandler"/> callback..
/// </summary>
/// <param name="handler"></param>
public void AddFadeChangedHandler(FadeChangeHandler handler)
{
FadeChanged += handler;
}
/// <summary>
/// Removes a <seealso cref="FadeChangeHandler"/> callback..
/// </summary>
/// <param name="handler"></param>
public void removeFadeChangedHandler(FadeChangeHandler handler)
{
FadeChanged -= handler;
}
/// <summary>
/// Starts the fade in
/// </summary>
void OnEnable()
{
fadeTime = Time.fixedTime;
updateFadeMaterial(FadeInColor);
}
void Update()
{
if (DelayStartTime >= 0.0f && DelayStartTime <= (Time.fixedTime - fadeTime))
{
DelayStartTime = -1.0f;
StartCoroutine(FadeIn(FadeChanged));
}
}
/// <summary>
/// Cleans up the fade material
/// </summary>
void OnDestroy()
{
if (fadeRenderer != null)
Destroy(fadeRenderer);
if (fadeMesh != null)
Destroy(fadeMesh);
}
/// <summary>
/// Fades the screen in or out.
/// </summary>
/// <param name="fadeType">The <see cref="FadeType"/> to use when fading (e.g. fade in or out)</param>
public void Fade(FadeType fadeType, float fadeTime = -1, bool useHandler = false)
{
switch (fadeType)
{
case FadeType.In:
StartCoroutine(FadeIn(useHandler ? FadeChanged : null, fadeTime));
break;
case FadeType.Out:
StartCoroutine(FadeOut(useHandler ? FadeChanged : null, fadeTime));
break;
}
}
/// <summary>
/// Fades alpha from 1.0 to 0.0
/// </summary>
IEnumerator FadeIn(FadeChangeHandler fadeHandler, float fadeTime = -1)
{
if (fadeTime < 0)
{
fadeTime = FadeTime;
}
float elapsedTime = 0.0f;
updateFadeMaterial(FadeInColor);
Color color = FadeInColor;
while (elapsedTime < fadeTime)
{
yield return fadeInstruction;
elapsedTime += Time.deltaTime;
color.a = 1.0f - Mathf.Clamp01(elapsedTime / fadeTime);
updateFadeMaterial(color);
}
isFading = false;
if (FadeChanged != null)
{
FadeChanged(gameObject, FadeType.In);
}
}
/// <summary>
/// Fades alpha from 0.0 to 1.0
/// </summary>
IEnumerator FadeOut(FadeChangeHandler fadeHandler = null, float fadeTime = -1)
{
if (fadeTime < 0)
{
fadeTime = FadeTime;
}
float elapsedTime = 0.0f;
updateFadeMaterial(FadeOutColor);
Color color = FadeOutColor;
isFading = true;
while (elapsedTime < fadeTime)
{
yield return fadeInstruction;
elapsedTime += Time.deltaTime;
color.a = Mathf.Clamp01(elapsedTime / fadeTime);
updateFadeMaterial(color);
}
if (FadeChanged != null)
{
FadeChanged(gameObject, FadeType.Out);
}
}
private void updateFadeMaterial(Color color)
{
fadeMaterial.SetColor("_color", color);
if (fadeMaterial != null)
{
fadeMaterial.color = color;
fadeRenderer.material = fadeMaterial;
fadeRenderer.enabled = isFading;
}
}
/// <summary>
/// Renders the fade overlay when attached to a camera object
/// </summary>
void OnPostRender()
{
if (isFading && fadeMaterial != null)
{
fadeMaterial.SetPass(0);
GL.PushMatrix();
GL.LoadOrtho();
GL.Color(fadeMaterial.GetColor("_color"));
GL.Begin(GL.QUADS);
GL.Vertex3(0f, 0f, -12f);
GL.Vertex3(0f, 1f, -12f);
GL.Vertex3(1f, 1f, -12f);
GL.Vertex3(1f, 0f, -12f);
GL.End();
GL.PopMatrix();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment