diff options
Diffstat (limited to 'Erika/Assets/Scripts/Unit/Components/UnitImageEffect.cs')
-rw-r--r-- | Erika/Assets/Scripts/Unit/Components/UnitImageEffect.cs | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/Erika/Assets/Scripts/Unit/Components/UnitImageEffect.cs b/Erika/Assets/Scripts/Unit/Components/UnitImageEffect.cs new file mode 100644 index 00000000..fcdd5c1f --- /dev/null +++ b/Erika/Assets/Scripts/Unit/Components/UnitImageEffect.cs @@ -0,0 +1,202 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine;
+
+// Unit的一种后处理效果,渲染到一个RT上,对这个RT做效果
+
+public class UnitImageEffectHolder +{ + public float size; + public GameObject gameObject; + public MeshRenderer renderer + { + get + { + if (gameObject == null) + return null; + return gameObject.GetComponent<MeshRenderer>(); + } + } +} + +public class UnitImageEffectHandle +{ + public delegate void UnitImageEffectStepCallback(float normalizedTime);
+ public delegate void UnitImageEffectEndCallback();
+
+ public float lifeTime; + public float curTime; + public UnitImageEffectHolder holder; + + public UnitImageEffectStepCallback stepFunc; + public UnitImageEffectEndCallback onStop; +} + +public class UnitImageEffect : UnitComponent +{ + public List<UnitImageEffectHandle> effects = new List<UnitImageEffectHandle>(); + + public static GameObject effectPlane; + + private Dictionary<float/*size*/, List<UnitImageEffectHolder>/*pool*/> m_HolderPool = new Dictionary<float, List<UnitImageEffectHolder>>(); + + private ObjectPool<UnitImageEffectHandle> m_HandlePool = new ObjectPool<UnitImageEffectHandle>(null, null); + + public override void OnUpdate() + { + base.OnUpdate(); + List<UnitImageEffectHandle> temp = ListPool<UnitImageEffectHandle>.Get(); + for(int i = 0; i < effects.Count; ++i) + { + var handle = effects[i]; + handle.curTime += Time.deltaTime; + if(handle.curTime > handle.lifeTime) + { + temp.Add(handle); + handle.onStop?.Invoke(); + continue; + } + handle.stepFunc?.Invoke(handle.curTime / handle.lifeTime); + } + for(int j = 0; j < temp.Count; j++) + { + temp[j].holder.gameObject.SetActive(false); + ReleaseHolder(ref temp[j].holder); + effects.Remove(temp[j]); + m_HandlePool.Release(temp[j]); + } + ListPool<UnitImageEffectHandle>.Release(temp); + } + + UnitImageEffectHolder ClaimHolder(float size) + { + List<UnitImageEffectHolder> holders; + if (m_HolderPool.TryGetValue(size, out holders)) + { + if (holders.Count > 0) + { + var holder = holders[holders.Count - 1]; + holders.RemoveAt(holders.Count - 1); + return holder; + } + } + UnitImageEffectHolder newHolder = new UnitImageEffectHolder(); + newHolder.size = size; + Mesh mesh = new Mesh(); + mesh.vertices = new Vector3[4] { + new Vector3(-size/2, size/2, 0), + new Vector3(size/2, size/2, 0), + new Vector3(size/2, -size/2, 0), + new Vector3(-size/2, -size/2, 0) + }; + mesh.uv = new Vector2[4] { + new Vector2(0, 1), + new Vector2(1, 1), + new Vector2(1, 0), + new Vector2(0, 0), + }; + mesh.triangles = new int[6] { + 0, 1, 3, + 1, 2, 3, + }; + mesh.UploadMeshData(true); + newHolder.gameObject = new GameObject("Image Effect Holder(" + size + "m)"); + MeshFilter filter = newHolder.gameObject.AddComponent<MeshFilter>(); + filter.sharedMesh = mesh; + MeshRenderer renderer = newHolder.gameObject.AddComponent<MeshRenderer>(); + renderer.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; + renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; + renderer.receiveShadows = false; + renderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; + renderer.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion; + renderer.allowOcclusionWhenDynamic = false; + return newHolder; + } + + void ReleaseHolder(ref UnitImageEffectHolder holder) + { + float size = holder.size; + List<UnitImageEffectHolder> holders; + if (!m_HolderPool.TryGetValue(size, out holders)) + { + holders = new List<UnitImageEffectHolder>(); + m_HolderPool.Add(size, holders); + } + holder.gameObject.SetActive(false); + holder.gameObject.transform.position = Vector3.zero; + holders.Add(holder); + holder = null; + }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ public void ShowMotionBlur(float lifeTime, float angle, float distance) + { + UnitImageEffectHandle handle = m_HandlePool.Get(); + + handle.lifeTime = lifeTime; + handle.curTime = 0; + float size = UnitManager.Instance.pc.unitDetail.snapshotBound; + handle.holder = ClaimHolder(size); + handle.holder.gameObject.SetActive(true); + string matPath = StaticDefine.imageEffectMaterails[EImageEffectMaterails.MotionBlur]; + handle.holder.renderer.sharedMaterial = ResourceManager.Instance.LoadAsset<Material>(matPath); + + MaterialPropertyBlock block = new MaterialPropertyBlock(); + handle.holder.renderer.GetPropertyBlock(block); + block.SetFloat("_Angle", angle); + block.SetFloat("_Distance", distance); + handle.holder.renderer.SetPropertyBlock(block); + + handle.stepFunc = (float normalTime) => + { + handle.holder.gameObject.transform.position = UnitManager.Instance.pc.center; + + handle.holder.renderer.GetPropertyBlock(block); + block.SetFloat("_Distance", /*(normalTime) * */distance); + handle.holder.renderer.SetPropertyBlock(block); + }; + + effects.Add(handle); + } + + public void ShowGlitch(float lifeTime, bool hideUnitInMainCamera = true) + { + PCController pc = UnitManager.Instance.pc as PCController;
+
+ UnitImageEffectHandle handle = m_HandlePool.Get(); + + handle.lifeTime = lifeTime; + handle.curTime = 0; + float size = UnitManager.Instance.pc.unitDetail.snapshotBound; + handle.holder = ClaimHolder(size); + handle.holder.gameObject.SetActive(true); + string matPath = StaticDefine.imageEffectMaterails[EImageEffectMaterails.Glitch]; + handle.holder.renderer.sharedMaterial = ResourceManager.Instance.LoadAsset<Material>(matPath); + + MaterialPropertyBlock block = new MaterialPropertyBlock(); + handle.holder.renderer.GetPropertyBlock(block); + handle.holder.renderer.SetPropertyBlock(block); + + handle.stepFunc = (float normalTime) => { + UnitCamera.Instance.Render(); + + handle.holder.gameObject.transform.position = UnitManager.Instance.pc.center; + + handle.holder.renderer.GetPropertyBlock(block); + handle.holder.renderer.SetPropertyBlock(block); + }; + + if (hideUnitInMainCamera)
+ {
+ pc.unitRender.SetVisibilityInAllCameras(false);
+ } + + handle.onStop = () => {
+ pc.unitRender.SetVisibilityInAllCameras(true);
+ };
+
+ effects.Add(handle); + } + +}
\ No newline at end of file |