利用三角函数曲线模拟3D水面波动效果(Mesh顶点变化)
发表于2019-01-08
这里用的是正弦曲线:y=Asin(ωx+φ)+k
A——振幅,当物体作轨迹符合正弦曲线的直线往复运动时,其值为行程的1/2
(ωx+φ)——相位,反映变量y所处的状态
φ——初相,x=0时的相位;反映在坐标系上则为图像的左右移动
k——偏距,反映在坐标系上则为图像的上移或下移
ω——角速度, 控制正弦周期(单位弧度内震动的次数)
利用正弦曲线修改Mesh的Y值,实现波纹波动效果。
using UnityEngine; using System.Collections; [RequireComponent(typeof(MeshFilter))] public class MeshWaterWave : MonoBehaviour { public enum WaveType { none, simple, multiply, } //高度(振幅) [SerializeField] float height = 0.5f; //速度(初相) [SerializeField] float speed = 1f; //X/Z方向系数 [SerializeField, Range(-1, 1)] float xDirection = 1; [SerializeField, Range(-1, 1)] float zDirection = 1; //幅度(角速度) [SerializeField, Range(0, 1)] float range = 1; //方式 [SerializeField] WaveType waveType; //Mesh及顶点 Mesh waveMesh; Vector3[] baseVertex; Vector3[] nowVertex; void Start() { waveMesh = GetComponent<MeshFilter>().mesh; baseVertex = waveMesh.vertices; nowVertex = new Vector3[baseVertex.Length]; } void Update() { switch(waveType) { case WaveType.simple: WaveSimple(); break; case WaveType.multiply: WaveMultiply(); break; default: break; } } void StartWave(WaveType type) { waveType = type; } void ResetWave() { waveType = WaveType.none; waveMesh.vertices = baseVertex; } //----- void WaveSimple() { for (int i = 0; i < baseVertex.Length; i++) { nowVertex[i] = baseVertex[i]; nowVertex[i].y += Mathf.Sin((Time.time * speed + nowVertex[i].x * xDirection + nowVertex[i].z * zDirection) * range) * height; } waveMesh.vertices = nowVertex; } void WaveMultiply() { for (int i = 0; i < baseVertex.Length; i++) { nowVertex[i] = baseVertex[i]; nowVertex[i].y += Mathf.Sin((Time.time * speed + baseVertex[i].x * xDirection) * range) * height + Mathf.Sin((Time.time * speed + baseVertex[i].z * zDirection) * range) * height; } waveMesh.vertices = nowVertex; } }