using UnityEngine; namespace AQUAS { public class AQUAS_UnderWaterEffect_Simple : MonoBehaviour { [Header("Underwater Settings")] [Range(0f, 0.1f)] public float distortionStrength = 0.025f; [Range(0f, 0.002f)] public float blurSize = 0.001f; [Range(0f, 10f)] public int blurSmoothness = 5; public bool enableWetLensEffect = true; [Range(0.5f, 3f)] public float wetLensDuration = 1f; [Space(10f)] [Header("Underwater Audio Settings")] public AudioClip underwaterAmbientSound; [Range(0f, 1f)] public float underwaterAmbientVolume = 0.5f; public AudioClip diveSplashSound; [Range(0f, 1f)] public float diveSplashVolume = 1f; public AudioClip surfaceSplashSound; [Range(0f, 1f)] public float surfaceSplashVolume = 0.2f; [Space(10f)] [Header("Bubble Spawn Settings")] [Range(5f, 50f)] public int maximumBubbleCount = 10; public bool spawnBubbles; private float fogDensity = 1f; private float maxFogDepth = 10f; private Color fogColor; private Color deepFogColor; private Color adjustedFogColor; private bool defaultFog; private Color defaultFogColor; private FogMode defaultFogMode; private float defaultFogDensity; private float t = 1f; private int realBlurSmoothness; private GameObject waterPlane; private Material underwaterMat; private Material blurMat; private RenderTexture underwaterBuffer; private RenderTexture buffer1; private RenderTexture buffer2; [HideInInspector] public bool underwater; [HideInInspector] public float waterLevel; private GameObject audioObject; private AudioSource underwaterAmbient; private AudioSource diveSplash; private AudioSource surfaceSplash; private bool diveSplashPlayed = true; private bool surfaceSplashPlayed = true; private GameObject bubbleContainer; private GameObject bubble; private AQUAS_BubbleBehaviour bubbleBehaviour; private float t2; private float bubbleSpawnTimer; private int maxBubbleCount; private int bubbleCount; private void Start() { defaultFog = RenderSettings.fog; defaultFogColor = RenderSettings.fogColor; defaultFogMode = RenderSettings.fogMode; defaultFogDensity = RenderSettings.fogDensity; underwaterMat = new Material(Shader.Find("Hidden/AQUAS/Underwater/Fog Simple")); blurMat = new Material(Shader.Find("Hidden/AQUAS/Underwater/Blur Simple")); float x = (float)Screen.width / (float)Screen.height; underwaterMat.SetTexture("_DistortionLens", (Texture2D)Resources.Load("distortion_ellipse", typeof(Texture2D))); underwaterMat.SetTexture("_DropletNormals", (Texture2D)Resources.Load("wet_lens_normal", typeof(Texture2D))); underwaterMat.SetTextureScale("_DropletNormals", new Vector2(x, 1f)); underwaterMat.SetTexture("_DropletCutout", (Texture2D)Resources.Load("wet_lens_cutout", typeof(Texture2D))); underwaterMat.SetTextureScale("_DropletCutout", new Vector2(x, 1f)); underwaterBuffer = new RenderTexture(Screen.width, Screen.height, 32, RenderTextureFormat.ARGB32); buffer1 = new RenderTexture(Screen.width, Screen.height, 32, RenderTextureFormat.ARGB32); buffer2 = new RenderTexture(Screen.width, Screen.height, 32, RenderTextureFormat.ARGB32); audioObject = new GameObject("Underwater Audio"); audioObject.transform.parent = base.transform; audioObject.hideFlags = HideFlags.HideAndDontSave; if (underwaterAmbientSound == null) { underwaterAmbientSound = (AudioClip)Resources.Load("underwater"); } if (diveSplashSound == null) { diveSplashSound = (AudioClip)Resources.Load("dive-splash"); } if (surfaceSplashSound == null) { surfaceSplashSound = (AudioClip)Resources.Load("surfacing-splash"); } underwaterAmbient = audioObject.AddComponent(); diveSplash = audioObject.AddComponent(); surfaceSplash = audioObject.AddComponent(); underwaterAmbient.clip = underwaterAmbientSound; diveSplash.clip = diveSplashSound; surfaceSplash.clip = surfaceSplashSound; diveSplash.loop = false; surfaceSplash.loop = false; bubble = (GameObject)Resources.Load("Bubble", typeof(GameObject)); bubbleBehaviour = bubble.GetComponent(); if (spawnBubbles) { bubbleContainer = new GameObject("Bubble Container"); bubbleContainer.hideFlags = HideFlags.HideAndDontSave; } } private void OnTriggerEnter(Collider other) { if (other.gameObject.name == "Static Boundary") { if (other.transform.parent == null) { waterPlane = GetComponent().waterplane; } else { waterPlane = other.transform.parent.gameObject; } other.GetComponent().enabled = true; fogColor = waterPlane.GetComponent().mainFogColor; deepFogColor = waterPlane.GetComponent().deepFogColor; fogDensity = waterPlane.GetComponent().mainFogDensity / 10f; maxFogDepth = waterPlane.GetComponent().maxFogDepth; waterPlane.GetComponent().sharedMaterials[1].shader = Shader.Find("AQUAS/Desktop/Back/Transparent Back"); } } private void OnTriggerExit(Collider other) { if (other.gameObject.name == "Static Boundary") { other.GetComponent().enabled = false; waterPlane.GetComponent().sharedMaterials[1].shader = Shader.Find("AQUAS/Desktop/Back/Transparent Back"); waterPlane = null; } } private void OnRenderImage(RenderTexture source, RenderTexture destination) { if (realBlurSmoothness > 0) { underwaterMat.SetFloat("_Distortion", distortionStrength); if (enableWetLensEffect) { underwaterMat.SetFloat("_Wetness", 1f - t); } Graphics.Blit(source, underwaterBuffer, underwaterMat); blurMat.SetFloat("_BlurSize", blurSize); if (realBlurSmoothness == 1) { Graphics.Blit(underwaterBuffer, destination, blurMat); } else if (realBlurSmoothness == 2) { Graphics.Blit(underwaterBuffer, buffer1, blurMat); Graphics.Blit(buffer1, destination, blurMat); buffer1.Release(); } else { if (realBlurSmoothness <= 2) { return; } for (int i = 0; i < realBlurSmoothness; i++) { if (i == 0) { Graphics.Blit(underwaterBuffer, buffer1, blurMat); } if (i == realBlurSmoothness - 1) { if (i % 2 == 1) { Graphics.Blit(buffer1, destination, blurMat); buffer1.Release(); } else { Graphics.Blit(buffer2, destination, blurMat); buffer2.Release(); } } if (i > 0 && i < realBlurSmoothness - 1) { if (i % 2 == 1) { Graphics.Blit(buffer1, buffer2, blurMat); buffer1.Release(); } else { Graphics.Blit(buffer2, buffer1, blurMat); buffer2.Release(); } } } } } else { underwaterMat.SetFloat("_Distortion", distortionStrength); if (enableWetLensEffect) { underwaterMat.SetFloat("_Wetness", 1f - t); } Graphics.Blit(source, destination, underwaterMat); blurMat.SetFloat("_BlurSize", blurSize); } } private void Update() { if (waterPlane != null) { if (waterPlane.GetComponent() != null && waterPlane.GetComponent().useDynamicMesh) { if (base.transform.position.y < waterLevel) { underwater = true; } else { underwater = false; } } else if (base.transform.position.y < waterPlane.transform.position.y) { underwater = true; } else { underwater = false; } adjustedFogColor = Color.Lerp(fogColor, deepFogColor, (waterPlane.transform.position.y - base.transform.position.y) / maxFogDepth); } else { underwater = false; } ToggleFog(underwater); WetLensDistortionSwitch(underwater); underwaterAmbient.volume = underwaterAmbientVolume; diveSplash.volume = diveSplashVolume; surfaceSplash.volume = surfaceSplashVolume; if (underwater) { t = 0f; realBlurSmoothness = blurSmoothness; surfaceSplashPlayed = false; if (!underwaterAmbient.isPlaying) { underwaterAmbient.Play(); } if (!diveSplashPlayed) { diveSplash.Play(); diveSplashPlayed = true; } if (spawnBubbles) { if (bubbleContainer == null) { bubbleContainer = new GameObject("Bubble Container"); } t2 += Time.deltaTime; BubbleSpawner(); } } else { t = Mathf.Min(t + Time.deltaTime / wetLensDuration, 1f); realBlurSmoothness = 0; diveSplashPlayed = false; if (underwaterAmbient.isPlaying) { underwaterAmbient.Stop(); } if (!surfaceSplashPlayed) { surfaceSplash.Play(); surfaceSplashPlayed = true; } t2 = 0f; bubbleSpawnTimer = 0f; maxBubbleCount = Random.Range(maximumBubbleCount / 2, maximumBubbleCount); bubbleCount = 0; } } private void ToggleFog(bool isUnderwater) { if (isUnderwater) { RenderSettings.fogMode = FogMode.Exponential; RenderSettings.fogDensity = fogDensity; RenderSettings.fogColor = adjustedFogColor; RenderSettings.fog = true; } else { RenderSettings.fog = defaultFog; RenderSettings.fogMode = defaultFogMode; RenderSettings.fogColor = defaultFogColor; RenderSettings.fogDensity = defaultFogDensity; } } private void WetLensDistortionSwitch(bool isUnderwater) { if (isUnderwater) { underwaterMat.SetFloat("_WetLensDistortionSwitch", 1f); } else { underwaterMat.SetFloat("_WetLensDistortionSwitch", 0f); } } private void BubbleSpawner() { if (t2 > bubbleSpawnTimer && maxBubbleCount > bubbleCount) { float num = Random.Range(0f, 0.06f); bubbleBehaviour.mainCamera = base.gameObject; if (waterPlane.GetComponent() != null && waterPlane.GetComponent().useDynamicMesh) { bubbleBehaviour.waterLevel = waterLevel; } else { bubbleBehaviour.waterLevel = waterPlane.transform.position.y; } bubbleBehaviour.averageUpdrift = 1f + Random.Range(-0.3f, 0.3f); bubble.transform.localScale += new Vector3(num, num, num); Object.Instantiate(bubble, new Vector3(base.transform.position.x + Random.Range(-0.5f, 0.5f), base.transform.position.y - 0.4f, base.transform.position.z + Random.Range(-0.5f, 0.5f)), Quaternion.identity).transform.SetParent(bubbleContainer.transform); bubbleSpawnTimer += Random.Range(0.02f, 0.1f); bubbleCount++; bubble.transform.localScale = new Vector3(0.06f, 0.06f, 0.06f); } else if (t2 > bubbleSpawnTimer && maxBubbleCount <= bubbleCount) { float num2 = Random.Range(0f, 0.06f); bubbleBehaviour.mainCamera = base.gameObject; if (waterPlane.GetComponent() != null && waterPlane.GetComponent().useDynamicMesh) { bubbleBehaviour.waterLevel = waterLevel; } else { bubbleBehaviour.waterLevel = waterPlane.transform.position.y; } bubbleBehaviour.averageUpdrift = 1f + Random.Range(-0.3f, 0.3f); bubble.transform.localScale += new Vector3(num2, num2, num2); Object.Instantiate(bubble, new Vector3(base.transform.position.x + Random.Range(-0.5f, 0.5f), base.transform.position.y - 0.4f, base.transform.position.z + Random.Range(-0.5f, 0.5f)), Quaternion.identity).transform.SetParent(bubbleContainer.transform); bubbleSpawnTimer += Random.Range(0.02f, 0.2f); bubble.transform.localScale = new Vector3(0.06f, 0.06f, 0.06f); } } } }