using System; using System.Collections; using BitStrap; using UnityEngine; [AddComponentMenu("Image Effects/Rain/RainEffect")] [ExecuteInEditMode] public class RainEffect : MonoBehaviour { public enum RainType { Single = 0, Double = 1, Triple = 2, Quadruple = 3 } [Serializable] private class NormData { public float timeLeft; public float intensity; public float acceleration = 0.1f; public float valx; public float valy; public float t; public float c; public float fadeSpeed; } public int typeCount = 10; public Shader shader; public RainType rainType = RainType.Triple; public Texture2D NormalMap; public Color rainColor = Color.gray; public bool FitToScreen; [Range(0.05f, 5f)] public float Intensity = 0.7f; [Range(0.05f, 1f)] public float Distortion = 0.6f; [Range(0f, 1f)] public float reliefEffect = 0.2f; [Range(0.1f, 50f)] public float Size = 0.75f; [Range(0f, 10f)] public float InitialVelocity; [Range(0f, 10f)] public float AccelerationMin = 0.06f; [Range(0f, 10f)] public float AccelerationMax = 0.2f; [Range(0.05f, 60f)] public float IntervalMin = 0.6f; [Range(0.05f, 60f)] public float IntervalMax = 1.4f; [Range(0.0001f, 3f)] public float FadeSpeedMin = 0.09f; [Range(0.0001f, 3f)] public float FadeSpeedMax = 0.09f; private Material mat; private Texture2D Overlay; private NormData[] normals; private int index { get { return (int)rainType; } } private void Awake() { if (!SystemInfo.supportsImageEffects) { base.enabled = false; return; } normals = new NormData[typeCount]; if (!shader) { shader = Resources.Load("RainEffectShader", typeof(Shader)) as Shader; } if (!NormalMap) { NormalMap = Resources.Load("NormRain", typeof(Texture2D)) as Texture2D; } mat = new Material(shader); mat.SetTexture("_NormalTex", NormalMap); Overlay = new Texture2D(1, 1, TextureFormat.ARGB32, false); Overlay.SetPixel(0, 0, rainColor); Overlay.Apply(); mat.SetTexture("_OverlayTex", Overlay); for (int i = 0; i < typeCount; i++) { normals[i] = new NormData(); normals[i].timeLeft = UnityEngine.Random.Range(0f, IntervalMax); } } private void Update() { Init(); for (int i = 0; i < typeCount; i++) { UpdateInstance(i); } } private void UpdateInstance(int i) { normals[i].t += Time.deltaTime; normals[i].timeLeft -= Time.deltaTime; normals[i].valy = normals[i].c + 0.5f * normals[i].t * normals[i].t * normals[i].acceleration * 0.1f + InitialVelocity * normals[i].t; normals[i].intensity = Mathf.Max(0f, normals[i].intensity - 0.5f * normals[i].t * normals[i].fadeSpeed * 0.1f); } private void Init() { if (IntervalMin > IntervalMax) { swap(ref IntervalMin, ref IntervalMax); } if (AccelerationMin > AccelerationMax) { swap(ref AccelerationMin, ref AccelerationMax); } if (FadeSpeedMin > FadeSpeedMax) { swap(ref FadeSpeedMin, ref FadeSpeedMax); } } private void swap(ref float a, ref float b) { float num = a; a = b; b = num; } private string s(int num) { return num.ToString(); } private void OnRenderImage(RenderTexture source, RenderTexture destination) { Overlay.SetPixel(0, 0, rainColor); Overlay.Apply(); mat.SetTexture("_NormalTex", NormalMap); mat.SetTexture("_OverlayTex", Overlay); mat.SetFloat("_Distortion", 0f - Distortion); mat.SetFloat("_Relief", reliefEffect); for (int i = 0; i < typeCount; i++) { mat.SetFloat("_Intensity" + s(i + 1), normals[i].intensity); mat.SetVector("_NormalOffsetScale" + s(i + 1), new Vector4(normals[i].valx, normals[i].valy, (!FitToScreen) ? ((float)Screen.width / (float)NormalMap.width * (1f - Size)) : (2.5f * (1f - Size)), (!FitToScreen) ? ((float)Screen.height / (float)NormalMap.height * (1f - Size)) : (2.5f * (1f - Size)))); } Graphics.Blit(source, destination, mat, index); } [Button] public void ShowDrops() { StartCoroutine(ShowDropsAnim()); } public IEnumerator ShowDropsAnim() { Intensity = 2f; for (int i = 0; i < typeCount; i++) { normals[i].t = 0f; normals[i].intensity = Intensity; normals[i].timeLeft = UnityEngine.Random.Range(IntervalMin, IntervalMax); normals[i].acceleration = UnityEngine.Random.Range(AccelerationMin, AccelerationMax); normals[i].valx = UnityEngine.Random.value; normals[i].valy = (normals[i].c = UnityEngine.Random.value); normals[i].fadeSpeed = UnityEngine.Random.Range(FadeSpeedMin, FadeSpeedMax); } yield return new WaitForSeconds(2f); LeanTween.value(2f, 0f, 3f).setOnUpdate(delegate(float val) { Intensity = val; }); yield return new WaitForSeconds(3f); yield return null; } }