利用三角函数曲线模拟3D水面波动效果(Mesh顶点变化)

发表于2019-01-08
评论0 4.6k浏览
这里用的是正弦曲线: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;
    }
}

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

标签: