rustum 发表于 2022-3-10 16:57

30行代码,在Unity制造一个风中飘舞的旗帜

0.效果



1.代码

using UnityEngine;
using DG.Tweening; //DoTween补间库,可以到AssetStore下载


public class ProceduralMesh : MonoBehaviour
{
    private int xValue, yValue;

    private MeshFilter meshFilter;
    private Mesh mesh;
    private Vector3[] vertices;
    private Vector3[,] vertices2dArray;
    private Vector3[,] vertices2dArray_Origin;

    private float rate = -1f;

    private void Start()
    {
      meshFilter = GetComponent<MeshFilter>();
      DOTween.To(() => rate, x => rate = x, 6, 2).SetLoops(-1, LoopType.Yoyo).SetEase(Ease.InOutSine);
      GenerateMesh();
    }

    private void Update()
    {
      //动画
      for (int x = 0; x <= xValue; x++)
      {
            for (int y = yValue; y > -1; y--)
            {
                Vector3 pos = vertices2dArray_Origin
                  + new Vector3(Mathf.Cos((270 + (yValue - y) * rate) * Mathf.Deg2Rad), 0);
                vertices2dArray = pos;
            }
      }

      for (int index = 0, y = 0; y <= yValue; y++)
      {
            for (int x = 0; x <= xValue; x++, index++)
            {
                vertices = vertices2dArray;
            }
      }

      mesh.vertices = vertices;
    }

    private void GenerateMesh()
    {
      //顶点 + UV
      vertices = new Vector3[(xValue + 1) * (yValue + 1)];
      vertices2dArray = new Vector3;
      vertices2dArray_Origin = new Vector3;
      Vector2[] uv = new Vector2;
      for (int i = 0, y = 0; y <= yValue; y++)
      {
            for (int x = 0; x <= xValue; x++, i++)
            {
                vertices = new Vector2(x, y);
                vertices2dArray = new Vector2(x, y);
                vertices2dArray_Origin = new Vector2(x, y);
                uv = new Vector2((float)x / xValue, (float)y / yValue);
            }
      }
      //三角形(ti:TriangleIndex,vi:VerticesIndex)
      int[] triangles = new int;
      for (int ti = 0, vi = 0, y = 0; y < yValue; y++, vi++)
      {
            for (int x = 0; x < xValue; x++, ti += 6, vi++)
            {
                triangles = vi;
                triangles = triangles = vi + 1;
                triangles = triangles = vi + xValue + 1;
                triangles = vi + xValue + 2;
            }
      }

      mesh = new Mesh() { vertices = vertices, triangles = triangles, uv = uv, name = "Flag" };
      meshFilter.mesh = mesh;
    }
}
2.简析


[*]首先生成一个正确的网格。
[*]每帧从旗帜的上方到下方依次改变顶点位置。
[*]创建一个pingpong型的补间数值,用这个数值驱动顶点位移,形成动画。
[*]注:另外需要注意的是,这种效果在正常情况下或许会选择在GPU实现来达到一个最佳性能,但是这篇短文是一个关于Mesh变形的简短示例,所以就用了一个这样的例子,请大家辩证看待。一来为初次接触Mesh编程的同学带来一个最最直观的示例,知道了Mesh编程究竟能做什么。二来为之后真正的Mesh变形+物理碰撞系列文章做一个基础铺垫。
3.源文件地址
页: [1]
查看完整版本: 30行代码,在Unity制造一个风中飘舞的旗帜