203 lines
5.2 KiB
C#
203 lines
5.2 KiB
C#
using UnityEngine;
|
||
using System.Collections;
|
||
|
||
public enum BlackType
|
||
{
|
||
ImmediatelyBlack,
|
||
PingPong,
|
||
EditCurve
|
||
}
|
||
|
||
[ExecuteInEditMode]
|
||
[RequireComponent(typeof(Camera))]
|
||
[AddComponentMenu("Image Effects/Black/BlackScreenCSharp")]
|
||
public class BlackScreenEffect : MonoBehaviour {
|
||
|
||
#region DataDeclaration
|
||
|
||
public Shader _blackScreenShader;
|
||
public float _TransTime = 1.0f;
|
||
static Material s_blackMaterial = null;
|
||
public bool _IsLoop = false;
|
||
public BlackType _BlackType = BlackType.ImmediatelyBlack;
|
||
public AnimationCurve _AnimationCurve = new AnimationCurve(new Keyframe(0.0f, 0.0f, 0.0f, 1.0f), new Keyframe(1.0f, 1.0f, 1.0f, 1.0f));
|
||
|
||
private float timeCounter ;
|
||
private float timeCounterAnim;
|
||
private bool isPingPongSecRange = false;
|
||
private bool isEnd = false;
|
||
#endregion
|
||
|
||
#region DataCheck
|
||
|
||
private BlackType BlackTypeFuc
|
||
{
|
||
get
|
||
{
|
||
return _BlackType;
|
||
}
|
||
}
|
||
|
||
protected Material material
|
||
{
|
||
get
|
||
{
|
||
if (s_blackMaterial == null)
|
||
{
|
||
s_blackMaterial = new Material(_blackScreenShader);
|
||
s_blackMaterial.hideFlags = HideFlags.DontSave;
|
||
}
|
||
return s_blackMaterial;
|
||
}
|
||
}
|
||
|
||
private void InitData()
|
||
{
|
||
if (BlackTypeFuc == BlackType.PingPong)
|
||
{
|
||
timeCounter = _TransTime;
|
||
}
|
||
else if (BlackTypeFuc == BlackType.ImmediatelyBlack)
|
||
{
|
||
timeCounter = 0.0f;
|
||
}
|
||
else
|
||
{
|
||
timeCounter = 0.0f;
|
||
timeCounterAnim = 0.0f;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region MainFunc
|
||
//黑屏淡入淡出计算时间。
|
||
void BlackScreenTimeEvaluate()
|
||
{
|
||
//当type设置为pingpong时,屏幕从亮到黑再到亮,过程总时间为2*_TransTime。
|
||
if (BlackTypeFuc == BlackType.PingPong)
|
||
{
|
||
//从亮到暗
|
||
if (!isPingPongSecRange)
|
||
{
|
||
timeCounter -= Time.deltaTime;
|
||
if (timeCounter < 0.0f)
|
||
{
|
||
isPingPongSecRange = true;
|
||
}
|
||
}
|
||
//从暗到亮
|
||
else
|
||
{
|
||
timeCounter += Time.deltaTime;
|
||
if (timeCounter > _TransTime)
|
||
{
|
||
isPingPongSecRange = false;
|
||
timeCounter = _TransTime;
|
||
if (!_IsLoop)
|
||
{
|
||
enabled = false;
|
||
//isEnd = true;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
//ImmediatelyBlack,瞬间黑屏,经过_TransTime的时间后变亮。
|
||
else if (BlackTypeFuc == BlackType.ImmediatelyBlack)
|
||
{
|
||
timeCounter += Time.deltaTime;
|
||
if (timeCounter > _TransTime)
|
||
{
|
||
if (!_IsLoop)
|
||
{
|
||
enabled = false;
|
||
isEnd = true;
|
||
}
|
||
else
|
||
{
|
||
timeCounter = 0.0f;
|
||
}
|
||
}
|
||
}
|
||
//EditCurve,解决参数化问题,时间的曲线变化随AnimationCurve编辑的曲线变动。
|
||
else
|
||
{
|
||
timeCounterAnim += Time.deltaTime;
|
||
timeCounter = _AnimationCurve.Evaluate(timeCounterAnim / _TransTime) * _TransTime;
|
||
if (timeCounterAnim > _TransTime)
|
||
{
|
||
if (!_IsLoop)
|
||
{
|
||
enabled = false;
|
||
isEnd = true;
|
||
}
|
||
else
|
||
{
|
||
timeCounterAnim = 0;
|
||
timeCounter = _AnimationCurve.Evaluate(0) * _TransTime;
|
||
}
|
||
}
|
||
}
|
||
|
||
material.SetFloat("_blackCount", timeCounter / _TransTime);
|
||
|
||
//无loop的时候,若在上段代码把以下参数设置为0会导致闪屏问题。
|
||
if (isEnd)
|
||
{
|
||
timeCounterAnim = 0.0f;
|
||
timeCounter = 0.0f;
|
||
isEnd = false;
|
||
}
|
||
|
||
}
|
||
#endregion
|
||
|
||
#region MonoBehaviourField
|
||
|
||
// Use this for initialization
|
||
void Start()
|
||
{
|
||
// Disable if we don't support image effects
|
||
if (!SystemInfo.supportsImageEffects)
|
||
{
|
||
enabled = false;
|
||
return;
|
||
}
|
||
// Disable if the shader can't run on the users graphics card
|
||
if (!_blackScreenShader || !material.shader.isSupported)
|
||
{
|
||
enabled = false;
|
||
return;
|
||
}
|
||
|
||
InitData();
|
||
}
|
||
|
||
protected void OnDisable()
|
||
{
|
||
if (s_blackMaterial)
|
||
{
|
||
Destroy(s_blackMaterial);
|
||
}
|
||
}
|
||
|
||
|
||
void OnRenderImage(RenderTexture source, RenderTexture destination)
|
||
{
|
||
//source.filterMode = FilterMode.Bilinear;
|
||
|
||
BlackScreenTimeEvaluate();
|
||
|
||
int rtW = source.width;
|
||
int rtH = source.height;
|
||
//当前屏幕(满分辨率)作为buffer使用shader渲染后到目标屏幕,并释放当前buffer。
|
||
RenderTexture buffer = RenderTexture.GetTemporary(rtW, rtH, 0);
|
||
Graphics.Blit(source, buffer, material, 0);
|
||
Graphics.Blit(buffer, destination);
|
||
RenderTexture.ReleaseTemporary(buffer);
|
||
}
|
||
#endregion
|
||
|
||
}
|