假如我们要创建如下一个网格,该怎么做呢?
这是个4x4的网格,一共有25个顶点,16x2个三角形。
建个坐标系如下图:
1.创建顶点:
如坐标系所示,我们的25个顶点为:
(0,4)(1,4)(2,4)(3,4)(4,4)
(0,3)(1,3)(2,3)(3,3)(4,3)
(0,2)(1,2)(2,2)(3,2)(4,2)
(0,1)(1,1)(2,1)(3,1)(4,1)
(0,0)(1,0)(2,0)(3,0)(4,0)
2.创建UV:
我们的UV坐标系如下图:
注意UV的坐标的u,v的取值为[0,1],所以实际上我们每个顶点对应的UV坐标就是
顶点坐标缩放到[0,1]范围内的值,在这里就是每个顶点的坐标除以4就得到了我们
的UV坐标。
这个时候对UV坐标施加一种变化(例如坐标每帧增加0.1,对1取模),就有了UV动画的说法。
3.生成三角形顶点index
1个三角形有3个顶点,我们的网格共有16x2=32个三角形,我们是不可能创建32x3个顶点的,
所以我们的三角形数据实际上是保存了顶点的索引。
如下图所示:
假设我们将上面4个顶点依序放进一个数组里面,那么
(0,0)对应索引为0
(1,0)对应索引为1
(1,1)对应索引为2
(0,1)对应索引为3
那么此时,
三角形1由3个顶点组成:(0,0)(1,0)(1,1),索引分别为0,1,2
三角形2由3个顶点组成:(0.0)(0,1)(1,1),索引分别为0,3,2
那么我们的三角形数据只保存索引值,就能达到4个顶点组成2个三角形,而不是6个顶点。
最后:
说的差不多了,那就上代码吧:
GeneratorEditor.cs:用来在Inspector上面显示按钮。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(MeshCreator))]
public class GeneratorEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector ();
MeshCreator script = (MeshCreator)target;
if (GUILayout.Button("Create Mesh"))
{
script.CreateMesh ();
}
}
}
MeshCreator.cs:创建网格的主要代码。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MeshCreator : MonoBehaviour
{
public int width = 10;
public int height = 10;
public void CreateMesh()
{
GenerateMesh();
}
private void GenerateMesh()
{
GameObject obj = new GameObject ();
MeshFilter meshFilter = obj.AddComponent<MeshFilter> ();
//创建mesh
Mesh mesh = new Mesh ();
meshFilter.mesh = mesh;
MeshRenderer renderer = obj.AddComponent<MeshRenderer> ();
//标准材质
Material mat = new Material (Shader.Find("Standard"));
mat.color = Color.green;
renderer.material = mat;
int y = 0;
int x = 0;
//创建顶点和UV
Vector3[] vertices = new Vector3[height * width];
Vector2[] uv = new Vector2[height * width];
//把uv缩放到0 - 1
Vector2 uvScale = new Vector2 (1.0f / (width - 1), 1.0f / (height - 1));
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
//生成顶点
vertices [y * width + x] = new Vector3 (x, 0, y);
//生成uv
uv [y * width + x] = Vector2.Scale (new Vector2 (x, y), uvScale);
}
}
mesh.vertices = vertices;
mesh.uv = uv;
//三角形index
int[] triangles = new int[(height - 1) * (width - 1) * 6];
int index = 0;
for (y = 0; y < height - 1; y++)
{
for (x = 0; x < width - 1; x++)
{
//每个格子2个三角形,总共6个index
triangles [index++] = (y * width) + x;
triangles [index++] = ((y + 1) * width) + x;
triangles [index++] = (y * width) + x + 1;
triangles [index++] = ((y + 1) * width) + x;
triangles [index++] = ((y + 1) * width) + x + 1;
triangles [index++] = (y * width) + x + 1;
}
}
mesh.triangles = triangles; //三角面
mesh.RecalculateNormals (); //计算法线
}
}
把MeshCreator.cs挂到一个GameObject上面如图:
点击一下Create Mesh按钮就能生成了。如图: