有时候需要通过代码来自定义 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 技术。