初识Unity Mesh
Mesh概念:Mesh是Unity中的一个组件,称为网格组件。通俗的讲,Mesh是指模型的网格,3D模型是由多边形拼接而成,而多边形实际上是由多个三角形拼接而成的。所以一个3D模型的表面其实是由多个彼此相连的三角面构成。三维空间中,构成这些三角形的点和边的集合就是Mesh。
Mesh组成:
1、顶点坐标数组vertexes
2、顶点在uv坐标系中的位置信息数组uvs
3、三角形顶点顺时针或者逆时针索引数组triangles
4、MeshFiler组件,用于增加mesh属性
5、MeshRender组件,增加材质并渲染出来。
6、可能还需要每个顶点的法线的数组normals
using UnityEngine; using UnityEditor; using System.Collections; public class GenMesh { [MenuItem("GameEditor/scene/Weather/GenMesh")] static public void GenMeshM() { Mesh m1 = CreateRect(); AssetDatabase.CreateAsset(m1, "Assets/_Resource/model/prefab/weather/m1.asset"); } public static Mesh CreateRect() { Mesh mesh = new Mesh(); int particleNum = 10; //顶点坐标 Vector3[] verts = new Vector3[4 * particleNum]; //uv坐标 Vector2[] uvs = new Vector2[4 * particleNum]; //三角形索引 int[] tris = new int[2 * 3 * particleNum]; Vector3 position; for (int i = 0; i < particleNum; i++) { int i4 = i * 4; int i6 = i * 6; position.x = 5 * i; position.y = 5 * i; position.z = 0; //顶点坐标 verts[i4 + 0] = position; verts[i4 + 1] = position + new Vector3(2, 0, 0); verts[i4 + 2] = position + new Vector3(2, 2, 0); verts[i4 + 3] = position + new Vector3(0, 2, 0); //四个顶点在UV坐标系中的位置 uvs[i4 + 0] = new Vector2(0.0f, 0.0f); uvs[i4 + 1] = new Vector2(1.0f, 0.0f); uvs[i4 + 2] = new Vector2(1.0f, 1.0f); uvs[i4 + 3] = new Vector2(0.0f, 1.0f); //顺时针绘制三角形0 1 2 / 0 2 3 tris[i6 + 0] = i4 + 0; tris[i6 + 1] = i4 + 1; tris[i6 + 2] = i4 + 2; tris[i6 + 3] = i4 + 0; tris[i6 + 4] = i4 + 2; tris[i6 + 5] = i4 + 3; } mesh.vertices = verts; mesh.triangles = tris; mesh.uv = uvs; mesh.RecalculateBounds(); return mesh; } public static Mesh CreateCircle() { Mesh mesh = new Mesh(); int particleNum = 10; Vector3[] verts = new Vector3[4 * particleNum]; Vector2[] uvs = new Vector2[4 * particleNum]; int[] tris = new int[2 * 3 * particleNum]; Vector3 position; for (int i = 0; i < particleNum; i++) { int i4 = i * 4; int i6 = i * 6; position.x = 5 * i; position.y = 5 * i; position.z = 0; verts[i4 + 0] = position; verts[i4 + 1] = position + new Vector3(2, 0, 0); verts[i4 + 2] = position + new Vector3(2, 2, 0); verts[i4 + 3] = position + new Vector3(0, 2, 0); uvs[i4 + 0] = new Vector2(0.0f, 0.0f); uvs[i4 + 1] = new Vector2(1.0f, 0.0f); uvs[i4 + 2] = new Vector2(1.0f, 1.0f); uvs[i4 + 3] = new Vector2(0.0f, 1.0f); //顺时针绘制三角形0 1 2 / 0 2 3 tris[i6 + 0] = i4 + 0; tris[i6 + 1] = i4 + 1; tris[i6 + 2] = i4 + 2; tris[i6 + 3] = i4 + 0; tris[i6 + 4] = i4 + 2; tris[i6 + 5] = i4 + 3; } mesh.vertices = verts; mesh.triangles = tris; mesh.uv = uvs; mesh.RecalculateBounds(); return mesh; } }
代码示例生成的mesh是这个样子,未添加MeshRender,即没有材质和渲染的情况:
添加MeshRender,即有材质和渲染的情况:
using UnityEngine; using System.Collections; /*仅仅创建Mesh * * */ public class CreatMesh : MonoBehaviour { private GameObject mMesh; private Material mMaterial; /* Mesh属性 * 长宽 * 段数 * 高度 * 高度差 */ private Vector2 size;//长度和宽度 private float minHeight = -10;//最小高度 private float maxHeight = 10;//最大高度 private Vector2 segment;//长度的段数和宽度的段数 private float unitH;//最小高度和最大高度只差,值为正 /* 顶点属性 * 顶点 * uv * 三角形 */ private Vector3[] vertexes;//顶点数 private Vector2 uvs;//uvs坐标 private int[] triangles;//三角形索引 void Start() { creatMesh(100, 100, 3, 3, -10, 10); } private void creatMesh(float width, float height, uint segmentX, uint segmentY, int min, int max) { size = new Vector2(width, height); maxHeight = max; minHeight = min; unitH = maxHeight - minHeight; segment = new Vector2(segmentX, segmentY); if (mMesh != null) { Destroy(mMesh); } mMesh = new GameObject(); mMesh.name = "CreateMesh"; computeVertexes(); DrawMesh(); } private void computeVertexes() { int sum = Mathf.FloorToInt((segment.x + 1) * (segment.y + 1));//顶点总数 float w = size.x / segment.x;//每一段的长度 float h = size.y / segment.y; GetTriangles(); int index = 0; vertexes = new Vector3[sum]; for (int i = 0; i < segment.y + 1; i++) { for (int j = 0; j < segment.x + 1; j++) { float tempHeight = 0; vertexes[index] = new Vector3(j * w, 0, i * h); index++; } } } private void DrawMesh() { Mesh mesh = mMesh.AddComponent<MeshFilter>().mesh;//网格 mMesh.AddComponent<MeshRenderer>();//网格渲染器 mMaterial = new Material(Shader.Find("Diffuse"));//材质 mMesh.GetComponent<Renderer>().material = mMaterial; /*设置mesh*/ mesh.Clear();//更新 mesh.vertices = vertexes; //mesh.uv mesh.triangles = triangles; mesh.RecalculateNormals(); mesh.RecalculateBounds(); } private int[] GetTriangles() { int sum = Mathf.FloorToInt(segment.x * segment.y * 6);//三角形顶点总数 triangles = new int[sum]; uint index = 0; for (int i = 0; i < segment.y; i++) { for (int j = 0; j < segment.x; j++) { int role = Mathf.FloorToInt(segment.x) + 1; int self = j + (i * role); int next = j + ((i + 1) * role); //顺时针 triangles[index] = self; triangles[index + 1] = next + 1; triangles[index + 2] = self + 1; triangles[index + 3] = self; triangles[index + 4] = next; triangles[index + 5] = next + 1; index += 6; } } return triangles; } }