概述
本篇为Unity Mesh基础的第一篇,通过一个最基本的平面四边形网格来进行阐述。在此之前先对网格(mesh)做一个简介。网格为最基本的模型表达,通过点构成线,再由线构成三角形,最后由三角形构成面,然后通过材质来进行网格表面的表达,如阴影,贴图等。Unity除了ui的mesh,其他都需要MeshFilter来确定网格形状,通过Material以及MeshRenderer来进行网格渲染。
Mesh的组成
Mesh由顶点组成,再有三个顶点构成。所以Mesh必须定义顶点以及顶点如何构成三角形,这是最基本的三个要素,其次还需要定义uv来确定贴图如何覆盖在图形表面,如果需要还需定义顶点的法线或者切向,法线跟光照有关,而切向则会影响纹理凹凸问题,本文以四边形为例进行阐述。
四边形顶点
顶点个数为4,即左下,右下,右上以及左上。size为正方向尺寸。
protected override Vector3[] Vertices
{
get
{
Vector3[] vertices = new Vector3[4];
vertices[0] = Vector3.zero * size;
vertices[1] = Vector3.right * size;
vertices[2] = new Vector3(1, 1, 0) * size;
vertices[3] = Vector3.up * size;
return vertices;
}
}
三角形排列
三角形排列为int类型数组,保存顶点的索引号,每三个组成一个三角形。下述代码即为左下,左上,右下组成第一个三角形,剩下组成第二个三角形,排列顺序为顺时针方向。
protected override int[] Triangles
{
get
{
int[] triangles = new int[6]
{
0,3,1,1,3,2
};
return triangles;
}
}
Mesh的uv
如果给网格赋值贴图,则需要定义uv,如下定义则为图片左下角对应mesh的左下角,右上角对应右上角。
protected override Vector2[] Uvs
{
get
{
Vector2[] uvs = new Vector2[4];
uvs[0] = new Vector2(0, 0);
uvs[1] = new Vector2(1, 0);
uvs[2] = new Vector2(1, 1);
uvs[3] = new Vector2(0, 1);
return uvs;
}
}
完整代码
基类
基类主要是通过OnDrawGizmos来绘制顶点,利于更直观观察。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))]
public class CreateMeshBase : MonoBehaviour
{
MeshFilter meshFilter;
protected Mesh mesh;
protected virtual Vector3[] Vertices { get; }
protected virtual int[] Triangles { get; }
protected virtual Vector3[] Normals { get; }
protected virtual Vector2[] Uvs { get; }
protected virtual string MeshName { get; }
protected virtual void Start()
{
GetMeshFilter();
}
protected virtual void Reset()
{
GetMeshFilter();
}
protected virtual void OnValidate()
{
GetMeshFilter();
}
void GetMeshFilter()
{
if (meshFilter == null)
{
meshFilter = GetComponent<MeshFilter>();
mesh = new Mesh();
}
mesh.triangles = null;
mesh.uv = null;
mesh.vertices = null;
mesh.name = MeshName;
mesh.vertices = Vertices;
mesh.triangles = Triangles;
mesh.uv = Uvs;
meshFilter.mesh = mesh;
}
private void OnDrawGizmos()
{
if (Vertices == null) return;
Gizmos.color = Color.red;
Gizmos.DrawSphere(Vector3.zero, 0.5f);
Gizmos.color = Color.blue;
for (int i = 0; i < Vertices.Length; i++)
{
Gizmos.DrawSphere(Vertices[i], 0.3f);
}
}
}
Quad参数
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CreateQuad : CreateMeshBase
{
public int size = 5;
protected override Vector3[] Vertices
{
get
{
Vector3[] vertices = new Vector3[4];
vertices[0] = Vector3.zero * size;
vertices[1] = Vector3.right * size;
vertices[2] = new Vector3(1, 1, 0) * size;
vertices[3] = Vector3.up * size;
return vertices;
}
}
protected override int[] Triangles
{
get
{
int[] triangles = new int[6]
{
0,3,1,1,3,2
};
return triangles;
}
}
protected override string MeshName
{
get
{
return "Simple quad";
}
}
protected override Vector2[] Uvs
{
get
{
Vector2[] uvs = new Vector2[4];
uvs[0] = new Vector2(0, 0);
uvs[1] = new Vector2(1, 0);
uvs[2] = new Vector2(1, 1);
uvs[3] = new Vector2(0, 1);
return uvs;
}
}
}
使用
使用时新建一个空游戏物体,挂载上述脚本,然后新建材质,并将材质赋值给MeshRenderer即可。