using System.Collections; using System.Collections.Generic; using Sirenix.OdinInspector; using UnityEngine; public class GerstnerWave : MonoBehaviour { [InfoBox("파도의 길이를 결정, 값이 클수록 파도 간의 간격이 커짐")] public float waveLength = 0.1f; [InfoBox("파도의 높이를 결정, 값이 클수록 파도의 높이가 커짐")] public float amplitude = 0.1f; [InfoBox("파도의 속도를 결정, 값이 클수록 파도의 속도가 오름")] public float speed = 1f; [InfoBox("파도의 방향을 결정")] public Vector2 direction = new Vector2(1.0f, 0.0f); private void FixedUpdate() { var mesh = GetComponent().mesh; var vertices = mesh.vertices; var normals = mesh.normals; var waveNumber = 2.0f * Mathf.PI / waveLength; var phaseConstant = speed * waveNumber; for (var i = 0; i < vertices.Length; i++) { var vertex = vertices[i]; var dotProduct = Vector2.Dot(new Vector2(vertex.x, vertex.z), direction); var wavePhase = waveNumber * dotProduct + phaseConstant * Time.time; vertex.y = amplitude * Mathf.Sin(wavePhase); vertices[i] = vertex; // Calculate the normal at the vertex var cosPhase = Mathf.Cos(wavePhase); var dx = -waveNumber * amplitude * direction.x * cosPhase; var 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) { var waveNumber = 2.0f * Mathf.PI / waveLength; var phaseConstant = speed * waveNumber; var dotProduct = Vector2.Dot(new Vector2(position.x + transform.position.x, position.z + transform.position.z), direction); var wavePhase = waveNumber * dotProduct + phaseConstant * Time.time; var cosPhase = Mathf.Cos(wavePhase); // We differentiate the wave function to get the slope at the current point var dx = -waveNumber * amplitude * direction.x * cosPhase; var dz = -waveNumber * amplitude * direction.y * cosPhase; var normal = new Vector3(dx, 1.0f, dz).normalized; return normal; } }