212 lines
5.9 KiB
C#
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()
|
|
};
|
|
}
|
|
}
|
|
}
|