using System.Collections; using System.Collections.Generic; using UnityEngine; public class GerstnerWave : MonoBehaviour { public float waveLength = 0.1f; public float amplitude = 0.1f; public float speed = 1f; public Vector2 direction = new Vector2(1.0f, 0.0f); void Update() { Mesh mesh = GetComponent().mesh; Vector3[] vertices = mesh.vertices; Vector3[] normals = mesh.normals; float waveNumber = 2.0f * Mathf.PI / waveLength; float phaseConstant = speed * waveNumber; for (int i = 0; i < vertices.Length; i++) { Vector3 vertex = vertices[i]; float dotProduct = Vector2.Dot(new Vector2(vertex.x, vertex.z), direction); float wavePhase = waveNumber * dotProduct + phaseConstant * Time.time; vertex.y = amplitude * Mathf.Sin(wavePhase); vertices[i] = vertex; // Calculate the normal at the vertex float cosPhase = Mathf.Cos(wavePhase); float dx = -waveNumber * amplitude * direction.x * cosPhase; float dz = -waveNumber * amplitude * direction.y * cosPhase; normals[i] = new Vector3(dx, 1.0f, dz).normalized; } mesh.vertices = vertices; mesh.normals = normals; } public Vector3 GetWaveNormal(Vector3 position) { float waveNumber = 2.0f * Mathf.PI / waveLength; float phaseConstant = speed * waveNumber; float dotProduct = Vector2.Dot(new Vector2(position.x + transform.position.x, position.z + transform.position.z), direction); float wavePhase = waveNumber * dotProduct + phaseConstant * Time.time; float cosPhase = Mathf.Cos(wavePhase); // We differentiate the wave function to get the slope at the current point float dx = -waveNumber * amplitude * direction.x * cosPhase; float dz = -waveNumber * amplitude * direction.y * cosPhase; Vector3 normal = new Vector3(dx, 1.0f, dz).normalized; return normal; } }