Files
UltimateFishing2020/Assets/Scripts/Assembly-CSharp/AQUAS/AQUAS_UnderWaterEffect.cs
2026-03-04 10:03:45 +08:00

527 lines
17 KiB
C#

using UnityEngine;
namespace AQUAS
{
public class AQUAS_UnderWaterEffect : MonoBehaviour
{
public enum QUALITY
{
low = 0,
medium = 1,
high = 2
}
[Header("Underwater Settings")]
public LayerMask cullingMask = -1;
public QUALITY backFaceQuality = QUALITY.medium;
[Range(0.1f, 1f)]
public float fogFade = 1f;
[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 deepFogDensity = 1.5f;
private float maxFogDepth = 10f;
private float adjustedFogDensity;
private Color fogColor;
private Color deepFogColor;
private Color adjustedFogColor;
private GameObject container;
private GameObject boundaryMask;
private GameObject volumeMask;
private GameObject frontFaceMask;
private GameObject background;
private GameObject waterPlane;
private GameObject[] waterObjects;
private GameObject[] staticBoundaries;
[HideInInspector]
public GameObject dynamicBoundary;
private Material fogMat;
private Material blurMat;
private Material dropletMaskMat;
[HideInInspector]
public RenderTexture mask;
private RenderTexture buffer1;
private RenderTexture buffer2;
private RenderTexture fogBuffer;
private RenderTexture dropletBuffer;
private RenderTexture dropletMask;
[HideInInspector]
public bool underwater;
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;
[HideInInspector]
public float waterLevel;
private void Start()
{
container = GameObject.Find("AQUAS Container");
if (container == null)
{
base.enabled = false;
return;
}
waterObjects = new GameObject[container.transform.childCount];
staticBoundaries = new GameObject[container.transform.childCount];
for (int i = 0; i < container.transform.childCount; i++)
{
waterObjects[i] = container.transform.GetChild(i).gameObject;
if (waterObjects[i].transform.Find("Static Boundary") != null)
{
staticBoundaries[i] = waterObjects[i].transform.Find("Static Boundary").gameObject;
}
else
{
staticBoundaries[i] = dynamicBoundary;
}
}
boundaryMask = new GameObject("Boundary Mask");
volumeMask = new GameObject("Volume Mask");
frontFaceMask = new GameObject("Front Face Mask");
background = new GameObject("Background");
boundaryMask.hideFlags = HideFlags.HideAndDontSave;
volumeMask.hideFlags = HideFlags.HideAndDontSave;
frontFaceMask.hideFlags = HideFlags.HideAndDontSave;
background.hideFlags = HideFlags.HideAndDontSave;
boundaryMask.transform.SetParent(base.transform);
boundaryMask.AddComponent<Camera>().CopyFrom(GetComponent<Camera>());
boundaryMask.GetComponent<Camera>().cullingMask &= -2 << LayerMask.NameToLayer("Everything");
boundaryMask.GetComponent<Camera>().cullingMask ^= 1 << LayerMask.NameToLayer("Water");
boundaryMask.GetComponent<Camera>().depth = GetComponent<Camera>().depth - 4f;
boundaryMask.AddComponent<AQUAS_BoundaryMask>();
boundaryMask.GetComponent<AQUAS_BoundaryMask>().nextCam = volumeMask;
boundaryMask.AddComponent<AQUAS_ReflectNot>();
volumeMask.transform.SetParent(base.transform);
volumeMask.AddComponent<Camera>().CopyFrom(GetComponent<Camera>());
volumeMask.GetComponent<Camera>().cullingMask &= -2 << LayerMask.NameToLayer("Everything");
volumeMask.GetComponent<Camera>().cullingMask ^= 1 << LayerMask.NameToLayer("Water");
volumeMask.GetComponent<Camera>().depth = GetComponent<Camera>().depth - 3f;
volumeMask.AddComponent<AQUAS_VolumeMask>();
volumeMask.GetComponent<AQUAS_VolumeMask>().nextCam = frontFaceMask;
volumeMask.AddComponent<AQUAS_ReflectNot>();
frontFaceMask.transform.SetParent(base.transform);
frontFaceMask.AddComponent<Camera>().CopyFrom(GetComponent<Camera>());
frontFaceMask.GetComponent<Camera>().cullingMask &= -2 << LayerMask.NameToLayer("Everything");
frontFaceMask.GetComponent<Camera>().cullingMask ^= 1 << LayerMask.NameToLayer("Water");
frontFaceMask.GetComponent<Camera>().depth = GetComponent<Camera>().depth - 2f;
frontFaceMask.AddComponent<AQUAS_FrontFaceMask>();
frontFaceMask.GetComponent<AQUAS_FrontFaceMask>().nextCam = base.gameObject;
frontFaceMask.AddComponent<AQUAS_ReflectNot>();
background.transform.SetParent(base.transform);
background.AddComponent<Camera>().CopyFrom(GetComponent<Camera>());
background.GetComponent<Camera>().cullingMask = cullingMask;
background.GetComponent<Camera>().cullingMask &= ~(1 << LayerMask.NameToLayer("Water"));
background.GetComponent<Camera>().depth = GetComponent<Camera>().depth - 1f;
background.AddComponent<AQUAS_CaptureBackground>();
background.AddComponent<AQUAS_ReflectNot>();
switch (backFaceQuality)
{
case QUALITY.low:
background.GetComponent<AQUAS_CaptureBackground>().quality = 3;
break;
case QUALITY.medium:
background.GetComponent<AQUAS_CaptureBackground>().quality = 2;
break;
case QUALITY.high:
background.GetComponent<AQUAS_CaptureBackground>().quality = 0;
break;
}
fogMat = new Material(Shader.Find("Hidden/AQUAS/Underwater/Fog"));
blurMat = new Material(Shader.Find("Hidden/AQUAS/Underwater/Blur"));
dropletMaskMat = new Material(Shader.Find("Hidden/AQUAS/Underwater/Droplet Mask"));
float x = (float)Screen.width / (float)Screen.height;
fogMat.SetTexture("_DistortionLens", (Texture2D)Resources.Load("distortion_ellipse", typeof(Texture2D)));
fogMat.SetTexture("_DropletNormals", (Texture2D)Resources.Load("wet_lens_normal", typeof(Texture2D)));
fogMat.SetTextureScale("_DropletNormals", new Vector2(x, 1f));
fogMat.SetTexture("_DropletCutout", (Texture2D)Resources.Load("wet_lens_cutout", typeof(Texture2D)));
fogMat.SetTextureScale("_DropletCutout", new Vector2(x, 1f));
mask = new RenderTexture(Screen.height, Screen.width, 8, RenderTextureFormat.ARGB32);
buffer1 = new RenderTexture(Screen.width, Screen.height, 32, RenderTextureFormat.ARGB32);
buffer2 = new RenderTexture(Screen.width, Screen.height, 32, RenderTextureFormat.ARGB32);
fogBuffer = new RenderTexture(Screen.width, Screen.height, 32, RenderTextureFormat.ARGB32);
dropletBuffer = new RenderTexture(Screen.width, Screen.height, 32, RenderTextureFormat.ARGB32);
dropletMask = 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<AudioSource>();
diveSplash = audioObject.AddComponent<AudioSource>();
surfaceSplash = audioObject.AddComponent<AudioSource>();
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<AQUAS_BubbleBehaviour>();
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<AQUAS_ProjectedGrid>().waterplane;
}
else
{
waterPlane = other.transform.parent.gameObject;
}
other.GetComponent<MeshRenderer>().enabled = true;
fogColor = waterPlane.GetComponent<AQUAS_UnderwaterParameters>().mainFogColor;
deepFogColor = waterPlane.GetComponent<AQUAS_UnderwaterParameters>().deepFogColor;
fogDensity = waterPlane.GetComponent<AQUAS_UnderwaterParameters>().mainFogDensity;
deepFogDensity = waterPlane.GetComponent<AQUAS_UnderwaterParameters>().deepFogDensity;
maxFogDepth = waterPlane.GetComponent<AQUAS_UnderwaterParameters>().maxFogDepth;
for (int i = 0; i < waterObjects.Length; i++)
{
waterObjects[i].layer = LayerMask.NameToLayer("Default");
staticBoundaries[i].layer = LayerMask.NameToLayer("Default");
}
boundaryMask.GetComponent<AQUAS_BoundaryMask>().boundaryObj = other.gameObject;
volumeMask.GetComponent<AQUAS_VolumeMask>().waterObj = waterPlane;
volumeMask.GetComponent<AQUAS_VolumeMask>().rend = waterPlane.GetComponent<Renderer>();
volumeMask.GetComponent<AQUAS_VolumeMask>().waterShaders[0] = waterPlane.GetComponent<Renderer>().sharedMaterials[0].shader;
volumeMask.GetComponent<AQUAS_VolumeMask>().waterShaders[1] = waterPlane.GetComponent<Renderer>().sharedMaterials[1].shader;
frontFaceMask.GetComponent<AQUAS_FrontFaceMask>().waterObj = waterPlane;
frontFaceMask.GetComponent<AQUAS_FrontFaceMask>().rend = waterPlane.GetComponent<Renderer>();
frontFaceMask.GetComponent<AQUAS_FrontFaceMask>().waterShaders[0] = waterPlane.GetComponent<Renderer>().sharedMaterials[0].shader;
frontFaceMask.GetComponent<AQUAS_FrontFaceMask>().waterShaders[1] = waterPlane.GetComponent<Renderer>().sharedMaterials[1].shader;
background.GetComponent<AQUAS_CaptureBackground>().waterObj = waterPlane;
background.GetComponent<AQUAS_CaptureBackground>().layerMask = cullingMask;
}
}
private void OnTriggerExit(Collider other)
{
if (other.gameObject.name == "Static Boundary")
{
other.GetComponent<MeshRenderer>().enabled = false;
waterPlane = null;
for (int i = 0; i < waterObjects.Length; i++)
{
waterObjects[i].layer = LayerMask.NameToLayer("Water");
staticBoundaries[i].layer = LayerMask.NameToLayer("Water");
}
boundaryMask.GetComponent<AQUAS_BoundaryMask>().boundaryObj = null;
volumeMask.GetComponent<AQUAS_VolumeMask>().waterObj = null;
frontFaceMask.GetComponent<AQUAS_FrontFaceMask>().waterObj = null;
background.GetComponent<AQUAS_CaptureBackground>().waterObj = null;
}
}
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
dropletMaskMat.SetTexture("_DropletMask", dropletMask);
dropletMaskMat.SetFloat("_Duration", wetLensDuration);
Graphics.Blit(mask, dropletBuffer, dropletMaskMat);
Graphics.Blit(dropletBuffer, dropletMask);
fogMat.SetTexture("_DropletMask", dropletMask);
if (blurSmoothness > 0)
{
fogMat.SetTexture("_DepthMask", mask);
fogMat.SetFloat("_Density", adjustedFogDensity);
fogMat.SetColor("_FogColor", adjustedFogColor);
fogMat.SetFloat("_Distortion", distortionStrength);
fogMat.SetFloat("_Fade", fogFade);
if (enableWetLensEffect)
{
fogMat.SetFloat("_EnableWetLens", 1f);
}
else
{
fogMat.SetFloat("_EnableWetLens", 0f);
}
Graphics.Blit(source, fogBuffer, fogMat);
blurMat.SetTexture("_DepthMask", mask);
blurMat.SetFloat("_BlurSize", blurSize);
if (blurSmoothness == 1)
{
Graphics.Blit(fogBuffer, destination, blurMat);
}
else if (blurSmoothness == 2)
{
Graphics.Blit(fogBuffer, buffer1, blurMat);
Graphics.Blit(buffer1, destination, blurMat);
buffer1.Release();
}
else
{
if (blurSmoothness <= 2)
{
return;
}
for (int i = 0; i < blurSmoothness; i++)
{
if (i == 0)
{
Graphics.Blit(fogBuffer, buffer1, blurMat);
}
if (i == blurSmoothness - 1)
{
if (i % 2 == 1)
{
Graphics.Blit(buffer1, destination, blurMat);
buffer1.Release();
}
else
{
Graphics.Blit(buffer2, destination, blurMat);
buffer2.Release();
}
}
if (i > 0 && i < blurSmoothness - 1)
{
if (i % 2 == 1)
{
Graphics.Blit(buffer1, buffer2, blurMat);
buffer1.Release();
}
else
{
Graphics.Blit(buffer2, buffer1, blurMat);
buffer2.Release();
}
}
}
}
}
else
{
fogMat.SetTexture("_DepthMask", mask);
fogMat.SetFloat("_Density", adjustedFogDensity);
fogMat.SetColor("_FogColor", adjustedFogColor);
fogMat.SetFloat("_Distortion", distortionStrength);
fogMat.SetFloat("_Fade", fogFade);
Graphics.Blit(source, destination, fogMat);
}
}
private void Update()
{
if (waterPlane != null)
{
if (waterPlane.GetComponent<AQUAS_CamLock>() != null && waterPlane.GetComponent<AQUAS_CamLock>().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;
}
underwaterAmbient.volume = underwaterAmbientVolume;
diveSplash.volume = diveSplashVolume;
surfaceSplash.volume = surfaceSplashVolume;
if (underwater)
{
surfaceSplashPlayed = false;
if (!underwaterAmbient.isPlaying)
{
underwaterAmbient.Play();
}
if (!diveSplashPlayed)
{
diveSplash.Play();
diveSplashPlayed = true;
}
if (spawnBubbles)
{
if (bubbleContainer == null)
{
bubbleContainer = new GameObject("Bubble Container");
bubbleContainer.hideFlags = HideFlags.HideAndDontSave;
}
t2 += Time.deltaTime;
BubbleSpawner();
}
}
else
{
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;
}
if (waterPlane != null)
{
adjustedFogDensity = Mathf.Lerp(fogDensity, deepFogDensity, (waterPlane.transform.position.y - base.transform.position.y) / maxFogDepth) * GetComponent<Camera>().farClipPlane / 10f;
adjustedFogColor = Color.Lerp(fogColor, deepFogColor, (waterPlane.transform.position.y - base.transform.position.y) / maxFogDepth);
}
}
private void BubbleSpawner()
{
if (t2 > bubbleSpawnTimer && maxBubbleCount > bubbleCount)
{
float num = Random.Range(0f, 0.06f);
bubbleBehaviour.mainCamera = base.gameObject;
if (waterPlane.GetComponent<AQUAS_CamLock>() != null && waterPlane.GetComponent<AQUAS_CamLock>().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(-3f, 3f), base.transform.position.y - 0.4f, base.transform.position.z + Random.Range(-3f, 3f)), 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<AQUAS_CamLock>() != null && waterPlane.GetComponent<AQUAS_CamLock>().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);
}
}
}
}