Created
February 14, 2020 20:45
-
-
Save hawkwood/41b0b361fdfa7a14acd21ae4a571f4dc to your computer and use it in GitHub Desktop.
LWRP friendly screen/headset fade for VRTK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class LWRPScreenFade : MonoBehaviour | |
{ | |
/// <summary> | |
/// The <see cref="Material"/> to use for the overlay. | |
/// </summary> | |
/// | |
[SerializeField] | |
private Color _OverlayColor = Color.black; | |
public Color OverlayColor { get { return _OverlayColor; } set { _OverlayColor = value; } } | |
[SerializeField] | |
private Material _OverlayMaterial; | |
public Material OverlayMaterial { get { return _OverlayMaterial; } set { _OverlayMaterial = value; } } | |
/// <summary> | |
/// The duration of time to apply the overlay <see cref="Color"/>. | |
/// </summary> | |
[SerializeField] | |
private float _AddDuration = 1; | |
public float AddDuration { get { return _AddDuration; } set { _AddDuration = value; } } | |
/// <summary> | |
/// The duration of time to remove the overlay <see cref="Color"/>. | |
/// </summary> | |
[SerializeField] | |
private float _RemoveDuration = 1; | |
public float RemoveDuration { get { return _RemoveDuration; } set { _RemoveDuration = value; } } | |
/// <summary> | |
/// The duration of time to wait once the overlay <see cref="Color"/> is applied before it is removed. | |
/// </summary> | |
[SerializeField] | |
private float _AppliedDuration; | |
public float AppliedDuration { get { return _AppliedDuration; } set { _AppliedDuration = value; } } | |
public bool IsAddTransitioning { get; protected set; } | |
/// <summary> | |
/// Whether an overlay remove transition is in progress. | |
/// </summary> | |
public bool IsRemoveTransitioning { get; protected set; } | |
/// <summary> | |
/// The target duration to process the color change for. | |
/// </summary> | |
protected float targetDuration; | |
/// <summary> | |
/// A copy of the <see cref="OverlayMaterial"/> to apply the transition overlay color on. | |
/// </summary> | |
protected Material workingMaterial; | |
/// <summary> | |
/// The target color to apply to the camera overlay during the process. | |
/// </summary> | |
protected Color targetColor = new Color(0f, 0f, 0f, 0f); | |
/// <summary> | |
/// The current color of the camera overlay during the process. | |
/// </summary> | |
protected Color currentColor = new Color(0f, 0f, 0f, 0f); | |
/// <summary> | |
/// The difference in color of the camera overlay during the process. | |
/// </summary> | |
protected Color deltaColor = new Color(0f, 0f, 0f, 0f); | |
/// <summary> | |
/// The routine for handling the fade in and out of the camera overlay. | |
/// </summary> | |
protected Coroutine blinkRoutine; | |
/// <summary> | |
/// Delays the reset of <see cref="blinkRoutine"/> by <see cref="AddDuration"/> plus <see cref="AppliedDuration"/> seconds. | |
/// </summary> | |
// protected WaitForSeconds resetDelayYieldInstruction; | |
private MeshRenderer fadeRenderer; | |
// private MeshFilter fadeMesh; | |
// public int renderQueue = 5000; | |
public void AddColorOverlay(Color overlayColor, float addDuration) | |
{ | |
OverlayColor = overlayColor; | |
AddDuration = addDuration; | |
AddColorOverlay(); | |
} | |
/// <summary> | |
/// Applies the <see cref="OverlayColor"/> to the cameras via <see cref="CameraValidity"/> over the given <see cref="AddDuration"/>. | |
/// </summary> | |
public void AddColorOverlay() | |
{ | |
ApplyColorOverlay(OverlayColor, AddDuration); | |
} | |
/// <summary> | |
/// Removes the <see cref="OverlayColor"/> to the cameras via <see cref="CameraValidity"/> over the given <see cref="RemoveDuration"/>. | |
/// </summary> | |
public void RemoveColorOverlay() | |
{ | |
ApplyColorOverlay(Color.clear, RemoveDuration); | |
} | |
/// <summary> | |
/// Applies the <see cref="OverlayColor"/> to the cameras via <see cref="CameraValidity"/> over the given <see cref="AddDuration"/> then waits for the given <see cref="AppliedDuration"/> then removes the <see cref="OverlayColor"/> over the given <see cref="RemoveDuration"/>. | |
/// </summary> | |
public void Blink() | |
{ | |
ApplyColorOverlay(OverlayColor, AddDuration); | |
blinkRoutine = StartCoroutine(ResetBlink()); | |
} | |
protected virtual void OnEnable() | |
{ | |
CopyMaterialOverlayToWorking(); | |
// OnAfterCheckDelayChange(); | |
// Camera.onPostRender += PostRender; | |
} | |
protected virtual void OnDisable() | |
{ | |
CancelBlinkRoutine(); | |
// Camera.onPostRender -= PostRender; | |
} | |
/// <summary> | |
/// Applies the given <see cref="Color"/> to the cameras via <see cref="CameraValidity"/> over the given duration. | |
/// </summary> | |
/// <param name="newColor"><see cref="Color"/> to apply to the overlay.</param> | |
/// <param name="duration">The duration over which the <see cref="Color"/> is applied.</param> | |
protected virtual void ApplyColorOverlay(Color newColor, float duration) | |
{ | |
CancelBlinkRoutine(); | |
if (newColor != targetColor || (Mathf.Abs(duration - targetDuration) > Mathf.Epsilon)) // !duration.ApproxEquals(targetDuration)) | |
{ | |
targetDuration = duration; | |
targetColor = newColor; | |
if (duration > 0.0f) | |
{ | |
deltaColor = (targetColor - currentColor) / duration; | |
} | |
else | |
{ | |
currentColor = newColor; | |
} | |
IsAddTransitioning = false; | |
IsRemoveTransitioning = false; | |
if (newColor != Color.clear) | |
{ | |
IsAddTransitioning = true; | |
// Added?.Invoke(eventData.Set(newColor)); | |
} | |
else | |
{ | |
IsRemoveTransitioning = true; | |
} | |
} | |
} | |
protected virtual IEnumerator ResetBlink() | |
{ | |
yield return new WaitForSeconds(AddDuration + AppliedDuration); | |
RemoveColorOverlay(); | |
} | |
/// <summary> | |
/// Cancels any existing running <see cref="ResetBlink(float)"/> Coroutine. | |
/// </summary> | |
protected virtual void CancelBlinkRoutine() | |
{ | |
if (blinkRoutine != null) | |
{ | |
StopCoroutine(blinkRoutine); | |
} | |
} | |
// Start is called before the first frame update | |
void Start() | |
{ | |
// create the fade material | |
// fadeMaterial = new Material(Shader.Find("Oculus/Unlit Transparent Color")); | |
MeshFilter fadeMesh = gameObject.AddComponent<MeshFilter>(); | |
fadeRenderer = gameObject.AddComponent<MeshRenderer>(); | |
var mesh = new Mesh(); | |
fadeMesh.mesh = mesh; | |
Vector3[] vertices = new Vector3[4]; | |
float width = 2f; | |
float height = 2f; | |
float depth = 1f; | |
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; | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
if (currentColor != targetColor) | |
{ | |
if (Mathf.Abs(currentColor.a - targetColor.a) < Mathf.Abs(deltaColor.a) * Time.deltaTime) | |
{ | |
currentColor = targetColor; | |
deltaColor = new Color(0, 0, 0, 0); | |
} | |
else | |
{ | |
currentColor += deltaColor * Time.deltaTime; | |
} | |
// Changed?.Invoke(eventData.Set(currentColor)); | |
} | |
else if (IsAddTransitioning) | |
{ | |
// AddTransitioned?.Invoke(eventData.Set(currentColor)); | |
IsAddTransitioning = false; | |
} | |
else if (IsRemoveTransitioning) | |
{ | |
// RemoveTransitioned?.Invoke(eventData.Set(currentColor)); | |
IsRemoveTransitioning = false; | |
} | |
if (currentColor.a > 0f && workingMaterial != null) | |
{ | |
currentColor.a = (targetColor.a > currentColor.a && currentColor.a > 0.98f ? 1f : currentColor.a); | |
workingMaterial.color = currentColor; | |
/* | |
workingMaterial.SetPass(0); | |
GL.PushMatrix(); | |
GL.LoadOrtho(); | |
GL.Color(workingMaterial.color); | |
GL.Begin(GL.QUADS); | |
GL.Vertex3(0f, 0f, 0.9999f); | |
GL.Vertex3(0f, 1f, 0.9999f); | |
GL.Vertex3(1f, 1f, 0.9999f); | |
GL.Vertex3(1f, 0f, 0.9999f); | |
GL.End(); | |
GL.PopMatrix(); | |
*/ | |
// workingMaterial.renderQueue = renderQueue; | |
fadeRenderer.material = workingMaterial; | |
fadeRenderer.enabled = true; | |
} | |
else | |
{ | |
fadeRenderer.enabled = false; | |
} | |
} | |
/* | |
private void SetMaterialAlpha() | |
{ | |
Color color = fadeColor; | |
color.a = Mathf.Max(currentAlpha, uiFadeAlpha); | |
isFading = color.a > 0; | |
if (fadeMaterial != null) | |
{ | |
fadeMaterial.color = color; | |
fadeMaterial.renderQueue = renderQueue; | |
fadeRenderer.material = fadeMaterial; | |
fadeRenderer.enabled = isFading; | |
} | |
} | |
*/ | |
protected void CopyMaterialOverlayToWorking() | |
{ | |
if (Application.isPlaying) | |
{ | |
Destroy(workingMaterial); | |
} | |
else | |
{ | |
DestroyImmediate(workingMaterial); | |
} | |
if (OverlayMaterial != null) | |
{ | |
workingMaterial = new Material(OverlayMaterial); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
OverlayMaterial should use this shader: