this needs one script attached to an empty GameObject and one material with texture
result video
public class WaveMesh : MonoBehaviour { private Mesh m_Mesh; private float size = 0.5f; private int gridSize = 8; public float waveFrequency = 5.0f; public float sizeScale = 0.5f; // Use this for initialization void Start () { } // Update is called once per frame void Update () { int dotsPerRow = gridSize + 1; int halfGridSize = gridSize / 2; Vector3[] verts = m_Mesh.vertices; float time = Time.time; for (int i = 0; i < dotsPerRow; i++) { for (int j = 0; j < dotsPerRow; j++) { int xIndex = j - halfGridSize; int yIndex = halfGridSize - i; float xSign = Mathf.Sign(xIndex); float ySign = Mathf.Sign(yIndex); float xPosTarget = xIndex; float yPosTarget = yIndex; //if (xIndex != 0 && yIndex != 0) { Vector2 wave = waveCoord(xIndex, yIndex, halfGridSize, time); verts[i * dotsPerRow + j] = new Vector3(wave.x, wave.y, 0.0f); } } } m_Mesh.vertices = verts; } private Vector2 waveCoord(float xIndex, float yIndex, float halfGridSize, float time) { Vector2 p = new Vector2(xIndex, yIndex); p = p * sizeScale; float len = p.magnitude; float sincValue = sinc(p.magnitude * 0.5f); float temp = Mathf.Cos(time * waveFrequency - len / sizeScale) * 0.5f * sizeScale * sincValue; Vector2 offset = new Vector2(Mathf.Sign(xIndex) * temp, Mathf.Sign(yIndex) * temp); return offset + p; } private float clampTimeToPeriod(float time, float period) { return time - Mathf.Floor(time / period); } private float sinc(float x) { if(Mathf.Abs(x) < 0.0001f) { return Mathf.Sin(x); } return Mathf.Sin(x) / x; } void Awake() { GameObject plane = new GameObject("CreatedWaveMesh"); MeshFilter meshFilter = (MeshFilter)plane.AddComponent(typeof(MeshFilter)); meshFilter.mesh = CreateMesh(); m_Mesh = meshFilter.mesh; MeshRenderer renderer = plane.AddComponent(typeof(MeshRenderer)) as MeshRenderer; //Load your material here Material newMat = Resources.Load("Materials/WaveStandardMaterial", typeof(Material)) as Material; renderer.material = newMat; //plane.transform.localScale = new Vector3(desiredSize / gridSize, desiredSize / gridSize, -1); plane.transform.localScale = new Vector3(1, 1, -1); plane.transform.localPosition = new Vector3(0.64f, 0.38f, -3); } Mesh CreateMesh() { Mesh m = new Mesh(); m.name = "ScriptedMesh"; /* case for gridSize == 4, there are 4x4=16 grids, dotsPerRow is 4+1=5 ..... ..... ..... ..... ..... */ int dotsPerRow = gridSize + 1; int halfGridSize = gridSize / 2; Vector3[] verts = new Vector3[dotsPerRow * dotsPerRow]; for (int i = 0; i < dotsPerRow; i++) { for(int j = 0; j < dotsPerRow; j++) { verts[i * dotsPerRow + j] = new Vector3(j - halfGridSize, halfGridSize - i, 0.0f); } } m.vertices = verts; Vector2[] uvs = new Vector2[verts.Length]; float dotsPerRowf = (float)dotsPerRow; for (int i = 0; i < dotsPerRow; i++) { for (int j = 0; j < dotsPerRow; j++) { uvs[i * dotsPerRow + j] = new Vector2((float)j / dotsPerRowf, 1.0f - (float)i / dotsPerRowf); } } m.uv = uvs; int numTris = gridSize * gridSize * 2; int[] tris = new int[numTris * 3]; for(int i = 0; i < gridSize; i++) { for(int j = 0; j < gridSize; j++) { int startIndex = 6 * (i * gridSize + j); tris[startIndex] = i * dotsPerRow + j; tris[startIndex + 1] = (i + 1) * dotsPerRow + j; tris[startIndex + 2] = i * dotsPerRow + j + 1; tris[startIndex + 3] = (i + 1) * dotsPerRow + j; tris[startIndex + 4] = (i + 1) * dotsPerRow + j + 1; tris[startIndex + 5] = i * dotsPerRow + j + 1; } } m.triangles = tris; m.RecalculateNormals(); return m; } }
沒有留言:
張貼留言