596 lines
15 KiB
C#
Executable File
596 lines
15 KiB
C#
Executable File
using UnityEngine;
|
|
using System.Collections;
|
|
|
|
public class ScreenWipe : MonoBehaviour
|
|
{
|
|
public enum ZoomType
|
|
{
|
|
Grow, Shrink
|
|
}
|
|
|
|
public enum TransitionType
|
|
{
|
|
Left, Right, Up, Down
|
|
}
|
|
|
|
private Texture tex;
|
|
private RenderTexture renderTex;
|
|
private Texture2D tex2D;
|
|
private float alpha;
|
|
private bool reEnableListener;
|
|
private Material shapeMaterial;
|
|
private Transform shape;
|
|
private AnimationCurve curve;
|
|
private bool useCurve;
|
|
public static ScreenWipe use;
|
|
|
|
|
|
|
|
void Awake ()
|
|
{
|
|
if (use)
|
|
{
|
|
Debug.LogWarning("Only one instance of ScreenCrossFadePro is allowed");
|
|
return;
|
|
}
|
|
use = this;
|
|
|
|
this.enabled = false;
|
|
}
|
|
|
|
void OnGUI ()
|
|
{
|
|
GUI.depth = -9999999;
|
|
GUI.color = new Color(GUI.color.r, GUI.color.g, GUI.color.b, alpha);
|
|
GUI.DrawTexture( new Rect(0, 0, Screen.width, Screen.height), tex);
|
|
}
|
|
|
|
IEnumerator AlphaTimer ( float time )
|
|
{
|
|
float rate = 1.0f/time;
|
|
|
|
if( useCurve )
|
|
{
|
|
float t = 0.0f;
|
|
|
|
while( t < 1.0f )
|
|
{
|
|
alpha = curve.Evaluate( t );
|
|
t += Time.deltaTime * rate;
|
|
yield return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (alpha = 1.0f; alpha > 0.0f; alpha -= Time.deltaTime * rate)
|
|
{
|
|
yield return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CameraSetup( Camera cam1, Camera cam2, bool cam1Active, bool enableThis )
|
|
{
|
|
if (enableThis)
|
|
{
|
|
this.enabled = true;
|
|
}
|
|
|
|
cam1.gameObject.active = cam1Active;
|
|
cam2.gameObject.active = true;
|
|
AudioListener listener = cam2.GetComponent<AudioListener>();
|
|
|
|
if (listener)
|
|
{
|
|
reEnableListener = listener.enabled? true : false;
|
|
listener.enabled = false;
|
|
}
|
|
}
|
|
|
|
void CameraCleanup ( Camera cam1, Camera cam2 )
|
|
{
|
|
AudioListener listener = cam2.GetComponent<AudioListener>();
|
|
if (listener && reEnableListener) {
|
|
listener.enabled = true;
|
|
}
|
|
cam1.gameObject.active = false;
|
|
this.enabled = false;
|
|
}
|
|
|
|
public IEnumerator CrossFadePro ( Camera cam1, Camera cam2, float time )
|
|
{
|
|
if (!renderTex)
|
|
{
|
|
renderTex = new RenderTexture(Screen.width, Screen.height, 24);
|
|
}
|
|
|
|
cam1.targetTexture = renderTex;
|
|
tex = renderTex;
|
|
CameraSetup (cam1, cam2, true, true);
|
|
|
|
// Debug.Log("CrossFadePro() begun");
|
|
yield return StartCoroutine( AlphaTimer( time ) );
|
|
|
|
// Debug.Log("CrossFadePro() finished");
|
|
cam1.targetTexture = null;
|
|
renderTex.Release();
|
|
CameraCleanup (cam1, cam2);
|
|
}
|
|
|
|
IEnumerator CrossFade ( Camera cam1, Camera cam2, float time )
|
|
{
|
|
yield return CrossFade( cam1, cam2, time, null );
|
|
}
|
|
|
|
public IEnumerator CrossFade ( Camera cam1, Camera cam2, float time, AnimationCurve _curve )
|
|
{
|
|
curve = _curve;
|
|
useCurve = curve != null;
|
|
|
|
if (!tex2D)
|
|
{
|
|
tex2D = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
|
|
}
|
|
|
|
tex2D.ReadPixels( new Rect(0, 0, Screen.width, Screen.height), 0, 0, false);
|
|
tex2D.Apply();
|
|
tex = tex2D;
|
|
yield return 0;
|
|
|
|
CameraSetup (cam1, cam2, false, true);
|
|
|
|
yield return AlphaTimer(time);
|
|
|
|
CameraCleanup (cam1, cam2);
|
|
}
|
|
|
|
IEnumerator RectWipe ( Camera cam1 , Camera cam2 , float time , ZoomType zoom )
|
|
{
|
|
yield return RectWipe( cam1, cam2, time, zoom, null );
|
|
}
|
|
|
|
public IEnumerator RectWipe ( Camera cam1 , Camera cam2 , float time , ZoomType zoom , AnimationCurve _curve )
|
|
{
|
|
curve = _curve;
|
|
useCurve = curve != null;
|
|
CameraSetup (cam1, cam2, true, false);
|
|
Camera useCam = (zoom == ZoomType.Shrink)? cam1 : cam2;
|
|
Camera otherCam = (zoom == ZoomType.Shrink)? cam2 : cam1;
|
|
Rect originalRect = useCam.rect;
|
|
float originalDepth = useCam.depth;
|
|
useCam.depth = otherCam.depth+1;
|
|
|
|
if( useCurve )
|
|
{
|
|
float rate= 1.0f/(time);
|
|
|
|
if (zoom == ZoomType.Shrink)
|
|
{
|
|
for (float i = 0.0f; i < 1.0f; i += Time.deltaTime * rate) {
|
|
float t = curve.Evaluate( i )*0.5f;
|
|
cam1.rect = new Rect(t, t, 1.0f-t*2, 1.0f-t*2);
|
|
yield return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (float i = 0.0f; i < 1.0f; i += Time.deltaTime * rate) {
|
|
float t = curve.Evaluate( i )*0.5f;
|
|
cam2.rect = new Rect(.5f - t, .5f - t, t * 2.0f, t * 2.0f);
|
|
yield return 0;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float rate = 1.0f/(time*2);
|
|
if (zoom == ZoomType.Shrink)
|
|
{
|
|
for (float i = 0.0f; i < .5; i += Time.deltaTime * rate)
|
|
{
|
|
float t = Mathf.Lerp(0.0f, .5f, Mathf.Sin(i * Mathf.PI)); // Slow down near the end
|
|
cam1.rect = new Rect(t, t, 1.0f-t*2, 1.0f-t*2);
|
|
yield return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (float i = 0.0f; i < .5f; i += Time.deltaTime * rate)
|
|
{
|
|
float t = Mathf.Lerp(.5f, 0.0f, Mathf.Sin((.5f-i) * Mathf.PI)); // Start out slower
|
|
cam2.rect = new Rect(.5f-t, .5f-t, t*2.0f, t*2.0f);
|
|
yield return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
useCam.rect = originalRect;
|
|
useCam.depth = originalDepth;
|
|
CameraCleanup (cam1, cam2);
|
|
}
|
|
|
|
IEnumerator ShapeWipe ( Camera cam1 , Camera cam2 , float time , ZoomType zoom , Mesh mesh , float rotateAmount )
|
|
{
|
|
yield return ShapeWipe( cam1, cam2, time, zoom, mesh, rotateAmount, null );
|
|
}
|
|
|
|
public IEnumerator ShapeWipe ( Camera cam1 , Camera cam2 , float time , ZoomType zoom , Mesh mesh , float rotateAmount , AnimationCurve _curve )
|
|
{
|
|
curve = _curve;
|
|
|
|
useCurve = curve != null;
|
|
|
|
if (!shapeMaterial)
|
|
{
|
|
shapeMaterial = new Material (
|
|
"Shader \"DepthMask\" {" +
|
|
" SubShader {" +
|
|
" Tags { \"Queue\" = \"Background\" }" +
|
|
" Lighting Off ZTest LEqual ZWrite On Cull Off ColorMask 0" +
|
|
" Pass {}" +
|
|
" }" +
|
|
"}"
|
|
);
|
|
}
|
|
|
|
if (!shape)
|
|
{
|
|
GameObject gobjShape = new GameObject("Shape");
|
|
gobjShape.AddComponent<MeshFilter>();
|
|
gobjShape.AddComponent<MeshRenderer>();
|
|
shape = gobjShape.transform;
|
|
shape.GetComponent<Renderer>().material = shapeMaterial;
|
|
}
|
|
|
|
CameraSetup (cam1, cam2, true, false);
|
|
Camera useCam = (zoom == ZoomType.Shrink)? cam1 : cam2;
|
|
Camera otherCam = (zoom == ZoomType.Shrink)? cam2 : cam1;
|
|
float originalDepth = otherCam.depth;
|
|
CameraClearFlags originalClearFlags = otherCam.clearFlags;
|
|
otherCam.depth = useCam.depth+1;
|
|
otherCam.clearFlags = CameraClearFlags.Depth;
|
|
|
|
shape.gameObject.active = true;
|
|
(shape.GetComponent<MeshFilter>() as MeshFilter).mesh = mesh;
|
|
shape.position = otherCam.transform.position + otherCam.transform.forward * (otherCam.nearClipPlane+.01f);
|
|
shape.parent = otherCam.transform;
|
|
shape.localRotation = Quaternion.identity;
|
|
|
|
if( useCurve )
|
|
{
|
|
float rate = 1.0f/time;
|
|
|
|
if (zoom == ZoomType.Shrink)
|
|
{
|
|
for (float i = 1.0f; i > 0.0f; i -= Time.deltaTime * rate)
|
|
{
|
|
float t = curve.Evaluate( i );
|
|
shape.localScale = new Vector3(t, t, t);
|
|
shape.localEulerAngles = new Vector3(0.0f, 0.0f, i * rotateAmount);
|
|
yield return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (float i = 0.0f; i < 1.0f; i += Time.deltaTime * rate)
|
|
{
|
|
float t = curve.Evaluate( i );
|
|
shape.localScale = new Vector3(t, t, t);
|
|
shape.localEulerAngles = new Vector3(0.0f, 0.0f, -i * rotateAmount);
|
|
yield return 0;
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
float rate = 1.0f/time;
|
|
if (zoom == ZoomType.Shrink) {
|
|
for (float i = 1.0f; i > 0.0f; i -= Time.deltaTime * rate) {
|
|
float t = Mathf.Lerp(1.0f, 0.0f, Mathf.Sin((1.0f-i) * Mathf.PI * 0.5f)); // Slow down near the end
|
|
shape.localScale = new Vector3(t, t, t);
|
|
shape.localEulerAngles = new Vector3(0.0f, 0.0f, i * rotateAmount);
|
|
yield return 0;
|
|
}
|
|
}
|
|
else {
|
|
for (float i = 0.0f; i < 1.0f; i += Time.deltaTime * rate) {
|
|
float t = Mathf.Lerp(1.0f, 0.0f, Mathf.Sin((1.0f-i) * Mathf.PI * 0.5f)); // Start out slower
|
|
shape.localScale = new Vector3(t, t, t);
|
|
shape.localEulerAngles = new Vector3(0.0f, 0.0f, -i * rotateAmount);
|
|
yield return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
otherCam.clearFlags = originalClearFlags;
|
|
otherCam.depth = originalDepth;
|
|
CameraCleanup (cam1, cam2);
|
|
shape.parent = null;
|
|
shape.gameObject.active = false;
|
|
}
|
|
|
|
IEnumerator SquishWipe ( Camera cam1 , Camera cam2 , float time , TransitionType transitionType )
|
|
{
|
|
yield return SquishWipe( cam1, cam2, time, transitionType, null );
|
|
}
|
|
|
|
public IEnumerator SquishWipe ( Camera cam1 , Camera cam2 , float time , TransitionType transitionType , AnimationCurve _curve )
|
|
{
|
|
curve = _curve;
|
|
useCurve = curve != null;
|
|
Rect originalCam1Rect = cam1.rect;
|
|
Rect originalCam2Rect = cam2.rect;
|
|
Matrix4x4 cam1Matrix = cam1.projectionMatrix;
|
|
Matrix4x4 cam2Matrix = cam2.projectionMatrix;
|
|
CameraSetup (cam1, cam2, true, false);
|
|
|
|
float rate = 1.0f/time;
|
|
float t = 0.0f;
|
|
float i = 0.0f;
|
|
|
|
while( i < 1.0f )
|
|
{
|
|
if( useCurve )
|
|
{
|
|
i = curve.Evaluate(t);
|
|
t += Time.deltaTime * rate;
|
|
}
|
|
else
|
|
{
|
|
i += Time.deltaTime * rate;
|
|
}
|
|
|
|
switch (transitionType)
|
|
{
|
|
case TransitionType.Right:
|
|
cam1.rect = new Rect(i, 0, 1.0f, 1.0f);
|
|
cam2.rect = new Rect(0, 0, i, 1.0f);
|
|
break;
|
|
case TransitionType.Left:
|
|
cam1.rect = new Rect(0, 0, 1.0f-i, 1.0f);
|
|
cam2.rect = new Rect(1.0f-i, 0, 1.0f, 1.0f);
|
|
break;
|
|
case TransitionType.Up:
|
|
cam1.rect = new Rect(0, i, 1.0f, 1.0f);
|
|
cam2.rect = new Rect(0, 0, 1.0f, i);
|
|
break;
|
|
case TransitionType.Down:
|
|
cam1.rect = new Rect(0, 0, 1.0f, 1.0f-i);
|
|
cam2.rect = new Rect(0, 1.0f-i, 1.0f, 1.0f);
|
|
break;
|
|
}
|
|
|
|
cam1.projectionMatrix = cam1Matrix;
|
|
cam2.projectionMatrix = cam2Matrix;
|
|
|
|
yield return 0;
|
|
}
|
|
|
|
cam1.rect = originalCam1Rect;
|
|
cam2.rect = originalCam2Rect;
|
|
CameraCleanup (cam1, cam2);
|
|
}
|
|
|
|
public int planeResolution = 90; // Higher numbers make the DreamWipe effect smoother, but take more CPU time
|
|
private Vector3[] baseVertices;
|
|
private Vector3[] newVertices;
|
|
private Material planeMaterial;
|
|
private GameObject plane;
|
|
private RenderTexture renderTex2;
|
|
|
|
public void InitializeDreamWipe ()
|
|
{
|
|
|
|
if (planeMaterial && plane) return;
|
|
|
|
Debug.Log("InitializeDreamWipe here!");
|
|
|
|
planeMaterial = new Material
|
|
(
|
|
"Shader \"Unlit2Pass\" {" +
|
|
"Properties {" +
|
|
" _Color (\"Main Color\", Color) = (1,1,1,1)" +
|
|
" _Tex1 (\"Base\", Rect) = \"white\" {}" +
|
|
" _Tex2 (\"Base\", Rect) = \"white\" {}" +
|
|
"}" +
|
|
"Category {" +
|
|
" ZWrite Off Alphatest Greater 0 ColorMask RGB Lighting Off" +
|
|
" Tags {\"Queue\"=\"Transparent\" \"IgnoreProjector\"=\"True\" \"RenderType\"=\"Transparent\"}" +
|
|
" Blend SrcAlpha OneMinusSrcAlpha" +
|
|
" SubShader {" +
|
|
" Pass {SetTexture [_Tex2]}" +
|
|
" Pass {SetTexture [_Tex1] {constantColor [_Color] Combine texture * constant, texture * constant}}" +
|
|
" }" +
|
|
"}}"
|
|
);
|
|
|
|
// Set up plane object
|
|
plane = new GameObject("Plane");
|
|
plane.AddComponent<MeshFilter>();
|
|
plane.AddComponent<MeshRenderer>();
|
|
plane.GetComponent<Renderer>().material = planeMaterial;
|
|
plane.GetComponent<Renderer>().castShadows = false;
|
|
plane.GetComponent<Renderer>().receiveShadows = false;
|
|
plane.GetComponent<Renderer>().enabled = false;
|
|
|
|
// Create the mesh used for the distortion effect
|
|
Mesh planeMesh = new Mesh();
|
|
(plane.GetComponent<MeshFilter>() as MeshFilter).mesh = planeMesh;
|
|
|
|
planeResolution = Mathf.Clamp(planeResolution, 1, 16380);
|
|
baseVertices = new Vector3[4*planeResolution + 4];
|
|
newVertices = new Vector3[baseVertices.Length];
|
|
Vector2[] newUV = new Vector2[baseVertices.Length];
|
|
int[] newTriangles = new int[18*planeResolution];
|
|
|
|
int idx = 0;
|
|
for (int i = 0; i <= planeResolution; i++)
|
|
{
|
|
float add = 1.0f/planeResolution*i;
|
|
newUV[idx] = new Vector2(0.0f, 1.0f-add);
|
|
baseVertices[idx++] = new Vector3(-1.0f, .5f-add, 0.0f);
|
|
newUV[idx] = new Vector2(0.0f, 1.0f-add);
|
|
baseVertices[idx++] = new Vector3(-.5f, .5f-add, 0.0f);
|
|
newUV[idx] = new Vector2(1.0f, 1.0f-add);
|
|
baseVertices[idx++] = new Vector3(.5f, .5f-add, 0.0f);
|
|
newUV[idx] = new Vector2(1.0f, 1.0f-add);
|
|
baseVertices[idx++] = new Vector3(1.0f, .5f-add, 0.0f);
|
|
}
|
|
|
|
idx = 0;
|
|
|
|
for (int y = 0; y < planeResolution; y++)
|
|
{
|
|
for (int x = 0; x < 3; x++) {
|
|
newTriangles[idx++] = (y*4 )+x;
|
|
newTriangles[idx++] = (y*4 )+x+1;
|
|
newTriangles[idx++] = ((y+1)*4)+x;
|
|
|
|
newTriangles[idx++] = ((y+1)*4)+x;
|
|
newTriangles[idx++] = (y *4)+x+1;
|
|
newTriangles[idx++] = ((y+1)*4)+x+1;
|
|
}
|
|
}
|
|
|
|
planeMesh.vertices = baseVertices;
|
|
planeMesh.uv = newUV;
|
|
planeMesh.triangles = newTriangles;
|
|
|
|
// Set up rendertextures
|
|
renderTex = new RenderTexture(Screen.width, Screen.height, 24);
|
|
renderTex2 = new RenderTexture(Screen.width, Screen.height, 24);
|
|
renderTex.filterMode = renderTex2.filterMode = FilterMode.Point;
|
|
planeMaterial.SetTexture("_Tex1", renderTex);
|
|
planeMaterial.SetTexture("_Tex2", renderTex2);
|
|
}
|
|
|
|
// IEnumerator DreamWipe ( Camera cam1 , Camera cam2 , float time )
|
|
// {
|
|
// yield return DreamWipe (cam1, cam2, time, .07f, 25.0f);
|
|
// }
|
|
|
|
public IEnumerator DreamWipe ( Camera cam1, Camera cam2, float time, float waveScale, float waveFrequency )
|
|
{
|
|
if (!plane)
|
|
{
|
|
InitializeDreamWipe();
|
|
}
|
|
|
|
waveScale = Mathf.Clamp(waveScale, -.5f, .5f);
|
|
waveFrequency = .25f/(planeResolution/waveFrequency);
|
|
|
|
CameraSetup (cam1, cam2, true, false);
|
|
|
|
Debug.Log("DreamWipe() begun");
|
|
|
|
// Make a camera that will show a plane with the combined rendertextures from cam1 and cam2,
|
|
// and make it have the highest depth so it's always on top
|
|
Camera cam2Clone = Instantiate(cam2, cam2.transform.position, cam2.transform.rotation) as Camera;
|
|
cam2Clone.depth = cam1.depth+1;
|
|
|
|
if (cam2Clone.depth <= cam2.depth)
|
|
{
|
|
cam2Clone.depth = cam2.depth+1;
|
|
}
|
|
|
|
// Get screen coodinates of 0,0 in local spatial coordinates, so we know how big to scale the plane (make sure clip planes are reasonable)
|
|
cam2Clone.nearClipPlane = .5f;
|
|
cam2Clone.farClipPlane = 1.0f;
|
|
Vector3 p = cam2Clone.transform.InverseTransformPoint(cam2.ScreenToWorldPoint(new Vector3(0.0f, 0.0f, cam2Clone.nearClipPlane)));
|
|
plane.transform.localScale = new Vector3(-p.x*2.0f, -p.y*2.0f, 1.0f);
|
|
plane.transform.parent = cam2Clone.transform;
|
|
plane.transform.localPosition = plane.transform.localEulerAngles = Vector3.zero;
|
|
|
|
// Must be a tiny bit beyond the nearClipPlane, or it might not show up
|
|
plane.transform.Translate(Vector3.forward * (cam2Clone.nearClipPlane+.00005f));
|
|
|
|
// Move the camera back so cam2 won't see the renderPlane, and parent it to cam2 so that if cam2 is moving, it won't see the plane
|
|
cam2Clone.transform.Translate(Vector3.forward * -1.0f);
|
|
cam2Clone.transform.parent = cam2.transform;
|
|
|
|
// Initialize some stuff
|
|
plane.GetComponent<Renderer>().enabled = true;
|
|
float scale = 0.0f;
|
|
Mesh planeMesh = plane.GetComponent<MeshFilter>().mesh;
|
|
cam1.targetTexture = renderTex;
|
|
cam2.targetTexture = renderTex2;
|
|
|
|
// Do the cross-fade
|
|
float rate = 1.0f/time;
|
|
|
|
for (float i = 0.0f; i < 1.0f; i += Time.deltaTime * rate)
|
|
{
|
|
planeMaterial.color = new Color( planeMaterial.color.r, planeMaterial.color.g, planeMaterial.color.b, Mathf.SmoothStep(0.0f, 1.0f, Mathf.InverseLerp(.75f, .15f, i)));
|
|
|
|
// Make plane undulate
|
|
for (int j = 0; j < newVertices.Length; j++) {
|
|
newVertices[j] = baseVertices[j];
|
|
newVertices[j].x += Mathf.Sin(j*waveFrequency + i*time) * scale;
|
|
}
|
|
|
|
planeMesh.vertices = newVertices;
|
|
scale = Mathf.Sin(Mathf.PI * Mathf.SmoothStep(0.0f, 1.0f, i)) * waveScale;
|
|
yield return 0;
|
|
}
|
|
|
|
Debug.Log("DreamWipe() finished");
|
|
|
|
// Clean up
|
|
CameraCleanup (cam1, cam2);
|
|
plane.GetComponent<Renderer>().enabled = false;
|
|
plane.transform.parent = null;
|
|
Destroy(cam2Clone.gameObject);
|
|
cam1.targetTexture = cam2.targetTexture = null;
|
|
renderTex.Release();
|
|
renderTex2.Release();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|