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(); 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(); 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(); 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(); if ((bool)component2) { component2.inertiaTensor = Vector3.one; component2.inertiaTensorRotation = Quaternion.identity; } if (meshCol == null) { meshCol = GetComponent(); if (meshCol == null) { meshCol = base.gameObject.AddComponent(); } } 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(); } }