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

212 lines
5.9 KiB
C#

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<Material> 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<ParticleSystem>();
particlesMove = particleObjectMove.GetComponent<ParticleSystem>();
particleRenderer = particleObject.GetComponent<ParticleSystemRenderer>();
particleRendererMove = particleObjectMove.GetComponent<ParticleSystemRenderer>();
mesh = body.GetComponent<MeshFilter>().mesh;
target = new RenderTexture(1024, 1024, 0, RenderTextureFormat.R8);
target.wrapMode = TextureWrapMode.Clamp;
target.filterMode = FilterMode.Bilinear;
target.anisoLevel = 0;
cam = GetComponent<Camera>();
cam.targetTexture = target;
waterMatList = new List<Material>();
for (int i = 0; i < waterPlane.GetComponent<Renderer>().sharedMaterials.Length; i++)
{
waterMatList.Add(waterPlane.GetComponent<Renderer>().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<Vector3> list = new List<Vector3>();
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()
};
}
}
}