405 lines
7.4 KiB
C#
405 lines
7.4 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
[ExecuteInEditMode]
|
|
public class MegaWaveMesh : MonoBehaviour
|
|
{
|
|
[HideInInspector]
|
|
public float offset;
|
|
|
|
public float Width = 1f;
|
|
|
|
public float Height = 1f;
|
|
|
|
public float Length;
|
|
|
|
public int WidthSegs = 1;
|
|
|
|
public bool GenUVs = true;
|
|
|
|
public bool recalcBounds;
|
|
|
|
public bool recalcNormals;
|
|
|
|
public bool recalcCollider;
|
|
|
|
public float mspeed = 1f;
|
|
|
|
public float flex = 1f;
|
|
|
|
public float amp;
|
|
|
|
public float wave = 1f;
|
|
|
|
public float phase;
|
|
|
|
public float mtime;
|
|
|
|
public float speed = 1f;
|
|
|
|
private float dist;
|
|
|
|
private float time;
|
|
|
|
public float flex1 = 1f;
|
|
|
|
public float amp1;
|
|
|
|
public float wave1 = 1f;
|
|
|
|
public float phase1;
|
|
|
|
public float mtime1;
|
|
|
|
public float speed1 = 1f;
|
|
|
|
private float dist1;
|
|
|
|
private float time1;
|
|
|
|
public float flex2 = 1f;
|
|
|
|
public float amp2;
|
|
|
|
public float wave2 = 1f;
|
|
|
|
public float phase2;
|
|
|
|
public float mtime2;
|
|
|
|
public float speed2 = 1f;
|
|
|
|
private float dist2;
|
|
|
|
private float time2;
|
|
|
|
public float amount = 1f;
|
|
|
|
[HideInInspector]
|
|
public int surfacestart;
|
|
|
|
[HideInInspector]
|
|
public int surfaceend = 1;
|
|
|
|
[HideInInspector]
|
|
public Vector3[] verts;
|
|
|
|
[HideInInspector]
|
|
public Vector2[] uvs;
|
|
|
|
[HideInInspector]
|
|
public int[] tris;
|
|
|
|
[HideInInspector]
|
|
public float surface;
|
|
|
|
public bool linkOffset;
|
|
|
|
[HideInInspector]
|
|
public bool rebuild = true;
|
|
|
|
private Material mat;
|
|
|
|
public Vector2 UVOffset = Vector2.zero;
|
|
|
|
public Vector2 UVScale = Vector2.one;
|
|
|
|
[HideInInspector]
|
|
public Mesh mesh;
|
|
|
|
public MeshCollider meshCol;
|
|
|
|
public Mesh colmesh;
|
|
|
|
public bool smooth = true;
|
|
|
|
private Vector3[] colverts;
|
|
|
|
public float colwidth = 1f;
|
|
|
|
private void Reset()
|
|
{
|
|
Rebuild();
|
|
}
|
|
|
|
public void Rebuild()
|
|
{
|
|
MeshFilter component = GetComponent<MeshFilter>();
|
|
if (!(component != null))
|
|
{
|
|
return;
|
|
}
|
|
Mesh mesh = component.sharedMesh;
|
|
if (mesh == null)
|
|
{
|
|
mesh = (component.sharedMesh = new Mesh());
|
|
}
|
|
this.mesh = mesh;
|
|
if (this.mesh != null)
|
|
{
|
|
BuildMesh(this.mesh);
|
|
MegaModifyObject component2 = GetComponent<MegaModifyObject>();
|
|
if (component2 != null)
|
|
{
|
|
component2.MeshUpdated();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (mesh == null)
|
|
{
|
|
Rebuild();
|
|
}
|
|
if (linkOffset)
|
|
{
|
|
offset = base.transform.position.x;
|
|
}
|
|
if (mat == null)
|
|
{
|
|
MeshRenderer component = GetComponent<MeshRenderer>();
|
|
if ((bool)component)
|
|
{
|
|
mat = component.sharedMaterial;
|
|
}
|
|
}
|
|
if ((bool)mat)
|
|
{
|
|
Vector3 vector = mat.mainTextureOffset;
|
|
vector.x = offset / Width;
|
|
mat.mainTextureOffset = vector;
|
|
}
|
|
if (wave == 0f)
|
|
{
|
|
wave = 1E-07f;
|
|
}
|
|
if (wave1 == 0f)
|
|
{
|
|
wave1 = 1E-07f;
|
|
}
|
|
if (wave2 == 0f)
|
|
{
|
|
wave2 = 1E-07f;
|
|
}
|
|
if (rebuild)
|
|
{
|
|
BuildMesh(mesh);
|
|
}
|
|
else
|
|
{
|
|
UpdateSurface();
|
|
mesh.vertices = verts;
|
|
if (recalcNormals)
|
|
{
|
|
mesh.RecalculateNormals();
|
|
}
|
|
if (recalcBounds)
|
|
{
|
|
mesh.RecalculateBounds();
|
|
}
|
|
}
|
|
if (recalcCollider)
|
|
{
|
|
Rigidbody component2 = GetComponent<Rigidbody>();
|
|
if ((bool)component2)
|
|
{
|
|
component2.inertiaTensor = Vector3.one;
|
|
component2.inertiaTensorRotation = Quaternion.identity;
|
|
}
|
|
if (meshCol == null)
|
|
{
|
|
meshCol = GetComponent<MeshCollider>();
|
|
if (meshCol == null)
|
|
{
|
|
meshCol = base.gameObject.AddComponent<MeshCollider>();
|
|
}
|
|
}
|
|
if (meshCol != null)
|
|
{
|
|
if (colmesh == null)
|
|
{
|
|
colmesh = new Mesh();
|
|
colmesh.Clear();
|
|
}
|
|
BuildCollider(colmesh);
|
|
meshCol.sharedMesh = null;
|
|
meshCol.sharedMesh = colmesh;
|
|
}
|
|
}
|
|
mtime += Time.deltaTime * speed * mspeed;
|
|
mtime1 += Time.deltaTime * speed1 * mspeed;
|
|
mtime2 += Time.deltaTime * speed2 * mspeed;
|
|
}
|
|
|
|
private void BuildCollider(Mesh cmesh)
|
|
{
|
|
bool flag = false;
|
|
if (colverts == null || colverts.Length != verts.Length)
|
|
{
|
|
colverts = new Vector3[verts.Length];
|
|
flag = true;
|
|
}
|
|
for (int i = 0; i < surfaceend; i++)
|
|
{
|
|
Vector3 vector = verts[i];
|
|
vector.z += colwidth;
|
|
colverts[i] = vector;
|
|
vector.z -= 2f * colwidth;
|
|
colverts[i + surfaceend] = vector;
|
|
}
|
|
colmesh.vertices = colverts;
|
|
if (flag)
|
|
{
|
|
colmesh.triangles = tris;
|
|
}
|
|
}
|
|
|
|
private void MakeQuad1(int f, int a, int b, int c, int d)
|
|
{
|
|
tris[f++] = c;
|
|
tris[f++] = b;
|
|
tris[f++] = a;
|
|
tris[f++] = a;
|
|
tris[f++] = d;
|
|
tris[f++] = c;
|
|
}
|
|
|
|
private int MaxComponent(Vector3 v)
|
|
{
|
|
if (Mathf.Abs(v.x) > Mathf.Abs(v.y))
|
|
{
|
|
if (Mathf.Abs(v.x) > Mathf.Abs(v.z))
|
|
{
|
|
return 0;
|
|
}
|
|
return 2;
|
|
}
|
|
if (Mathf.Abs(v.y) > Mathf.Abs(v.z))
|
|
{
|
|
return 1;
|
|
}
|
|
return 2;
|
|
}
|
|
|
|
public static float WaveFunc(float radius, float t, float amp, float waveLen, float phase)
|
|
{
|
|
float f = (float)Math.PI * 2f * (radius / waveLen + phase);
|
|
return amp * Mathf.Sin(f);
|
|
}
|
|
|
|
public static float WaveFunc1(float radius, float t, float amp, float waveLen, float phase)
|
|
{
|
|
float num = Mathf.Repeat((float)Math.PI * 2f * (radius / waveLen + phase), (float)Math.PI * 2f);
|
|
if (num < (float)Math.PI)
|
|
{
|
|
return (0f - amp) * Mathf.Sin(num);
|
|
}
|
|
return amp * Mathf.Sin(num);
|
|
}
|
|
|
|
public float Map(Vector3 p)
|
|
{
|
|
float num = Mathf.Abs(2f * p.y / dist);
|
|
num *= num;
|
|
p.y = 0f;
|
|
p.y += amount * flex * WaveFunc(p.x + offset, time, amp, wave, phase + mtime);
|
|
p.y += amount * flex1 * WaveFunc(p.x + offset, time1, amp1, wave1, phase1 + mtime1);
|
|
p.y += amount * flex2 * WaveFunc(p.x + offset, time2, amp2, wave2, phase2 + mtime2);
|
|
return p.y + surface;
|
|
}
|
|
|
|
private void UpdateSurface()
|
|
{
|
|
dist = wave / 10f * 4f * 5f;
|
|
if (dist == 0f)
|
|
{
|
|
dist = 1f;
|
|
}
|
|
dist1 = wave1 / 10f * 4f * 5f;
|
|
if (dist1 == 0f)
|
|
{
|
|
dist1 = 1f;
|
|
}
|
|
dist2 = wave2 / 10f * 4f * 5f;
|
|
if (dist2 == 0f)
|
|
{
|
|
dist2 = 1f;
|
|
}
|
|
for (int i = surfacestart; i < surfaceend; i++)
|
|
{
|
|
verts[i].y = Map(verts[i]);
|
|
}
|
|
}
|
|
|
|
private void BuildMesh(Mesh mesh)
|
|
{
|
|
Width = Mathf.Clamp(Width, 0f, float.MaxValue);
|
|
Length = Mathf.Clamp(Length, 0f, float.MaxValue);
|
|
Height = Mathf.Clamp(Height, 0f, float.MaxValue);
|
|
WidthSegs = Mathf.Clamp(WidthSegs, 1, 200);
|
|
Vector3 vector = new Vector3(Width, Height, Length) / 2f;
|
|
Vector3 zero = Vector3.zero;
|
|
zero.x = 0f - vector.x;
|
|
zero.y = vector.y;
|
|
zero.z = vector.z;
|
|
float num = Width / (float)WidthSegs;
|
|
float height = Height;
|
|
Vector3 vector2 = zero;
|
|
int num2 = 2 * (WidthSegs + 1);
|
|
surfacestart = 0;
|
|
surfaceend = WidthSegs + 1;
|
|
verts = new Vector3[num2];
|
|
uvs = new Vector2[num2];
|
|
tris = new int[WidthSegs * 2 * 3];
|
|
Vector2 zero2 = Vector2.zero;
|
|
int num3 = 0;
|
|
surface = zero.y;
|
|
vector2.z = zero.z;
|
|
vector2.y = zero.y;
|
|
vector2.x = zero.x;
|
|
for (int i = 0; i <= WidthSegs; i++)
|
|
{
|
|
verts[num3] = vector2;
|
|
if (GenUVs)
|
|
{
|
|
zero2.x = (vector2.x + vector.x + UVOffset.x) / Width * UVScale.x;
|
|
zero2.y = (vector2.y + vector.y + UVOffset.y) / Height * UVScale.y;
|
|
uvs[num3] = zero2;
|
|
}
|
|
num3++;
|
|
vector2.x += num;
|
|
}
|
|
vector2.y -= height;
|
|
vector2.x = zero.x;
|
|
for (int j = 0; j <= WidthSegs; j++)
|
|
{
|
|
verts[num3] = vector2;
|
|
if (GenUVs)
|
|
{
|
|
zero2.x = (vector2.x + vector.x + UVOffset.x) / Width * UVScale.x;
|
|
zero2.y = (vector2.y + vector.y + UVOffset.y) / Height * UVScale.y;
|
|
uvs[num3] = zero2;
|
|
}
|
|
vector2.x += num;
|
|
num3++;
|
|
}
|
|
int num4 = 0;
|
|
int num5 = 0;
|
|
for (int k = 0; k < WidthSegs; k++)
|
|
{
|
|
MakeQuad1(num4, num5, num5 + WidthSegs + 1, num5 + WidthSegs + 2, num5 + 1);
|
|
num4 += 6;
|
|
num5++;
|
|
}
|
|
UpdateSurface();
|
|
mesh.Clear();
|
|
mesh.subMeshCount = 1;
|
|
mesh.vertices = verts;
|
|
mesh.uv = uvs;
|
|
mesh.SetTriangles(tris, 0);
|
|
mesh.RecalculateNormals();
|
|
mesh.RecalculateBounds();
|
|
}
|
|
}
|