using System; using System.Collections.Generic; using UnityEngine; namespace AQUAS { public class AQUAS_RippleController : MonoBehaviour { public GameObject body; private GameObject particleObject; private GameObject particleObjectMove; private Camera cam; private ParticleSystem particles; private ParticleSystem.MainModule main; private ParticleSystem.EmissionModule emission; private ParticleSystem.ShapeModule shape; private ParticleSystemRenderer particleRenderer; private ParticleSystem particlesMove; private ParticleSystem.MainModule mainMove; private ParticleSystem.EmissionModule emissionMove; private ParticleSystem.ShapeModule shapeMove; private ParticleSystemRenderer particleRendererMove; private float maxBound; private Vector3 lastPosition; private float speed; private Vector2 firstVec; private Vector2 secondVec; private float angle; private float startLifetime = 2f; private float startSize = 5f; private float rateOverTime = 2f; private float shapeSize = 0.25f; private Mesh mesh; private Mesh referenceMesh; public float waterLevel; private bool ceaseRipples; private RenderTexture target; public GameObject waterPlane; private List waterMatList; private Material[] waterMat; public int index; private void Start() { particleObject = base.transform.Find("Particle System").gameObject; particleObjectMove = base.transform.Find("Particle System Move").gameObject; particles = particleObject.GetComponent(); particlesMove = particleObjectMove.GetComponent(); particleRenderer = particleObject.GetComponent(); particleRendererMove = particleObjectMove.GetComponent(); mesh = body.GetComponent().mesh; target = new RenderTexture(1024, 1024, 0, RenderTextureFormat.R8); target.wrapMode = TextureWrapMode.Clamp; target.filterMode = FilterMode.Bilinear; target.anisoLevel = 0; cam = GetComponent(); cam.targetTexture = target; waterMatList = new List(); for (int i = 0; i < waterPlane.GetComponent().sharedMaterials.Length; i++) { waterMatList.Add(waterPlane.GetComponent().sharedMaterials[i]); } waterMat = waterMatList.ToArray(); waterLevel = waterPlane.transform.position.y; particleObject.hideFlags = HideFlags.HideAndDontSave; particleObjectMove.hideFlags = HideFlags.HideAndDontSave; base.gameObject.hideFlags = HideFlags.HideInHierarchy; } private void OnPreCull() { if (body == null) { UnityEngine.Object.DestroyImmediate(base.gameObject); } main = particles.main; emission = particles.emission; shape = particles.shape; mainMove = particlesMove.main; emissionMove = particlesMove.emission; shapeMove = particlesMove.shape; particleRenderer.enabled = true; particleRendererMove.enabled = true; lastPosition = base.transform.position; base.transform.position = new Vector3(body.transform.position.x, -10000f, body.transform.position.z); speed = Vector3.Distance(base.transform.position, lastPosition) * 1f / Time.deltaTime; firstVec = new Vector2(0f, 1f); secondVec = new Vector2(base.transform.position.x - lastPosition.x, base.transform.position.z - lastPosition.z); angle = 0f - Vector2.SignedAngle(firstVec, secondVec); maxBound = Mathf.Max(mesh.bounds.extents.x * body.transform.localScale.x, mesh.bounds.extents.z * body.transform.localScale.z); cam.orthographicSize = 30f * maxBound; startLifetime = Mathf.Sqrt(3f * maxBound); startSize = 7f * maxBound; rateOverTime = 2f / maxBound; shapeSize = maxBound / 2f; if (speed > 0f) { startLifetime /= Mathf.Max(Mathf.Sqrt(2f * maxBound), speed / 10f); rateOverTime *= speed * 1.5f; main.startLifetimeMultiplier = startLifetime; main.startSizeMultiplier = startSize; mainMove.startLifetimeMultiplier = startLifetime; mainMove.startSizeMultiplier = startSize; mainMove.startRotation = MathF.PI / 180f * angle; emissionMove.rateOverTimeMultiplier = rateOverTime; emission.rateOverTimeMultiplier = 0f; } else { main.startLifetimeMultiplier = startLifetime; main.startSizeMultiplier = startSize; mainMove.startLifetimeMultiplier = startLifetime; mainMove.startSizeMultiplier = startSize; mainMove.startRotation = 0f; emissionMove.rateOverTimeMultiplier = 0f; emission.rateOverTimeMultiplier = rateOverTime; } shape.radius = shapeSize; shapeMove.radius = shapeSize; if (body.transform.position.y - mesh.bounds.extents.y < waterLevel && body.transform.position.y + mesh.bounds.extents.y > waterLevel) { ceaseRipples = false; } else { ceaseRipples = true; } if (ceaseRipples) { emission.rateOverTimeMultiplier = 0f; emissionMove.rateOverTimeMultiplier = 0f; } } private void OnPostRender() { Material[] array = waterMat; foreach (Material obj in array) { obj.SetTexture("_RippleTex" + index, target); obj.SetFloat("_XOffset" + index, 0f - base.transform.position.x); obj.SetFloat("_ZOffset" + index, 0f - base.transform.position.z); obj.SetFloat("_Scale" + index, cam.orthographicSize * 2f); } particleRenderer.enabled = false; particleRendererMove.enabled = false; } private Mesh getRelevantMesh(Mesh inputMesh, bool underwaterObject) { Vector3[] vertices = inputMesh.vertices; List list = new List(); if (underwaterObject) { for (int i = 0; i < vertices.Length; i++) { if (body.transform.TransformPoint(vertices[i]).y >= waterLevel) { list.Add(vertices[i]); } } } else { for (int j = 0; j < vertices.Length; j++) { if (body.transform.TransformPoint(vertices[j]).y <= waterLevel) { list.Add(vertices[j]); } } } return new Mesh { vertices = list.ToArray() }; } } }