有时候需要通过代码来自定义 mesh,以绘制特定的模型图形。除了直接用代码控制,也可以通过 shader 实现,这里介绍的是代码控制的方法。

基本思路是修改 mesh 的顶点与三角形索引,从而达到自定义形状的目的,与之前介绍的垂直 UI.Text 显示有异曲同工之处。

一个 mesh 由顶点信息和对应的三角形组合构成。

如图中的一个 Quad,有 4 个顶点,编号为 0、1、2、3,可以组合为 2 个三角形:三角形 1 由顶点 0、1、2 组成,三角形 2 由顶点 2、3、0 组成,合在一起构成一个面。

上图是 4 个顶点加一个三角形,组合为一个面的示意。

又如图中 4 个顶点配合 2 个三角形生成的图形,构成了 2 个面。

再比如 4 个顶点配合 3 个三角形,可以生成 3 个面。需要注意的是,三角形顶点顺序为顺时针时,渲染的是你希望看到的正面;逆时针则渲染的是反面。

示例代码

 void OnDrawGizmos()
    {
        MeshFilter filter = this.GetComponent<MeshFilter>();
        MeshRenderer render = this.GetComponent<MeshRenderer>();
        var mesh = filter.mesh;

        var ts = this.GetComponentsInChildren<Transform>();

        Vector3[] vers = new Vector3[ts.Length];

        for (int i = 0; i < ts.Length; i++)
        {
            vers[i] = ts[i].position;
        }

         var tris = new int[] { 0, 1, 2, 0,1,3,1,2,3 };

        //   mesh.Clear();
        mesh.vertices = vers;
        mesh.triangles = tris;
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();
        this.GetComponent<MeshCollider>().sharedMesh = mesh;
        filter.mesh = mesh;

    }

这与 Lite2D engine 中的顶点处理方式有几分相似——建模本质上也是在做同样的事。之所以需要用代码生成网格,是因为有些模型网格必须动态生成,例如地形破坏效果,如下图所示:

上图来自游戏《异星探险家》,流体计算等场景同样会用到这类动态 mesh 技术。