找回密码
 立即注册
查看: 321|回复: 0

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

[复制链接]
发表于 2022-3-10 16:57 | 显示全部楼层 |阅读模式
0.效果



1.代码

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

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class ProceduralMesh : MonoBehaviour
{
    [SerializeField] 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[x, y]
                    + new Vector3(Mathf.Cos((270 + (yValue - y) * rate) * Mathf.Deg2Rad), 0);
                vertices2dArray[x, y] = pos;
            }
        }

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

        mesh.vertices = vertices;
    }

    private void GenerateMesh()
    {
        //顶点 + UV
        vertices = new Vector3[(xValue + 1) * (yValue + 1)];
        vertices2dArray = new Vector3[xValue + 1, yValue + 1];
        vertices2dArray_Origin = new Vector3[xValue + 1, yValue + 1];
        Vector2[] uv = new Vector2[vertices.Length];
        for (int i = 0, y = 0; y <= yValue; y++)
        {
            for (int x = 0; x <= xValue; x++, i++)
            {
                vertices = new Vector2(x, y);
                vertices2dArray[x, y] = new Vector2(x, y);
                vertices2dArray_Origin[x, y] = new Vector2(x, y);
                uv = new Vector2((float)x / xValue, (float)y / yValue);
            }
        }
        //三角形(ti:TriangleIndex,vi:VerticesIndex)
        int[] triangles = new int[xValue * yValue * 6];
        for (int ti = 0, vi = 0, y = 0; y < yValue; y++, vi++)
        {
            for (int x = 0; x < xValue; x++, ti += 6, vi++)
            {
                triangles[ti] = vi;
                triangles[ti + 3] = triangles[ti + 2] = vi + 1;
                triangles[ti + 4] = triangles[ti + 1] = vi + xValue + 1;
                triangles[ti + 5] = 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.源文件地址

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-3 06:38 , Processed in 0.091051 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表