Unity 3D 创建Mesh(一)
一、Unity 3D 创建面片(Mesh)
Mesh是一种网格,可以产生像地形那样震撼的效果,那么怎样创建Mesh呢?那就要知道Mesh包含什么!
Mesh(网格):顶点、三角形、段数。
如图所示:该网格该如何表示呢?
顶点(vertexes) | 16=4*4 |
段数(segment) | 3*3 |
三角形(triangles) | 18 |
二、创建Mesh属性
我们来创建一个长宽为100m*100m,高度为0m,段数为3*3的网格,如上图所示
/* Mesh属性
* 长宽
* 段数
* 高度
*/
private Vector2 size;//长度和宽度
private float height= 0;//高度
private Vector2 segment;//长度的段数和宽度的段数
/* 顶点属性
* 顶点
* uv
* 三角形
*/
private Vector3[] vertexes;//顶点数
private int[] triangles;//三角形索引
/*计算顶点,存入顶点数组*/
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 int[] GetTriangles()
{
int sum = Mathf.FloorToInt(segment.x * segment.y * 6);//三角形顶点总数:假设是1*1的网格,会有2个顶点复用,因此是6个顶点。假设是2*2的网格,则是4个1*1的网格,即4*6即2*2*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;
}
到此:顶点、三角形计算完成!接下来是渲染。
三、渲染网格
在Unity 3D中,一个GameObject只有一个transform组件。我们在程序中,声明一个GameObject变量,通过添加MeshFilter来增加Mesh属性,通过MeshRenderer渲染出来,在MeshRenderer中,我们使用默认材质球。
private GameObject mMesh;
private Material mMaterial;
mMesh = new GameObject();
mMesh.name = "CreateMesh";
</pre><pre code_snippet_id="655703" snippet_file_name="blog_20150429_12_2096575" name="code" class="cpp"> 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();
}
四、完整代码(有点不一样,扩充了点,拖在摄像机下面即可)
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;
}
}