文章目录
- 前言
- 一、Mesh组成
- 二、使用步骤
- GetVertices方法
- GetNormal方法
- GetTriangles方法
- OnDrawGizmos方法
- 三、效果
- 四、总结
前言
本篇将使用C#脚本实现在Unity中创建平面,并通过调整顶点、UV坐标和三角形来生成Unity Logo 的效果。
一、Mesh组成
顶点(vertex):顶点是物体表面上的点,用 Vector3 类型表示它们在局部空间中的位置。
法线(normal):法线是顶点的方向,用 Vector3 类型表示它们在局部空间中的单位向量。
UV 坐标(uv):UV 坐标是顶点的纹理坐标,用 Vector2 类型表示它们在纹理图像中的位置。
三角形(triangle):三角形是物体表面上的面,用整数数组表示它们由哪些顶点组成。每个三角形由三个顶点索引构成,顶点索引是顶点数组中的位置。
二、使用步骤
首先,我们需要在 Unity 中创建一个空的 3D 项目。然后,我们需要在场景中添加一个空的游戏对象,我们可以把它命名为 “Triangle” ,这将是我们的网格生成器。为了让我们的网格能够显示在屏幕上,我们还需要给它添加一些组件,分别是:
MeshFilter:这个组件允许我们上传和存储我们的网格数据,以供 Unity 的图形 API 渲染。
MeshRenderer:这个组件负责渲染我们的网格,我们给它指定一个材质来改变网格的颜色和外观。
C# 脚本:这个组件是我们编写网格生成逻辑的地方,我们把它命名为 “Test”
下图是我们的游戏对象在inspector面板中的样子:
首先,我们需要在游戏对象上添加MeshFilter组件和MeshRenderer组件。这可以通过RequireComponent属性来实现,它会在挂载脚本的时候,自动添加指定的组件。
//挂载脚本的时候,自动添加下面的组件
[RequireComponent(typeof(MeshFilter)),RequireComponent(typeof(MeshRenderer))]
在Start方法中,我们首先创建了一个Mesh对象,并将其赋值给MeshFilter组件。然后,我们启动一个协程GeneratePlane()来生成平面。
private void Start()
{
_mesh = new Mesh();
GetComponent<MeshFilter>().mesh = _mesh;
_mesh.name = "Mesh02";
StartCoroutine(GeneratePlane());
}
GeneratePlane协程用于生成平面。首先调用GetVertices()方法来生成顶点,然后设置Mesh的顶点、UV坐标和法线。接着调用GetTriangles()方法来生成三角形。
private IEnumerator GeneratePlane()
{
yield return GetVertices();
// 设置 _mesh 的顶点、UV 和法线
_mesh.vertices = _vertices;
_mesh.uv = _uv;
_mesh.normals = _normal;
yield return GetTriangles();
}
GetVertices方法
用于生成顶点。通过嵌套循环,在二维平面上生成一系列顶点,并计算UV坐标和法线。
private IEnumerator GetVertices()
{
_vertices = new Vector3[(sequenceX + 1) * (sequenceY + 1)];
_uv = new Vector2[_vertices.Length];
_normal = new Vector3[_vertices.Length];
int i = 0;
for (int y = 0; y < sequenceY + 1; y++)
{
for (int x = 0; x < sequenceX + 1; x++)
{
_vertices[i] = new Vector3(x, y);
_uv[i] = new Vector2((float)x / sequenceX, (float)y / sequenceY);
_normal[i] = GetNormal(y);
i++;
yield return new WaitForSeconds(0.2f);
}
}
}
GetNormal方法
用于获取顶点的法线。这里简单地根据奇偶行返回不同的法线方向
private Vector3 GetNormal(int y)
{
// 如果 y 是偶数,则返回向上的法线,否则返回向下的法线
return y % 2 == 0 ? Vector3.up : Vector3.down;
}
GetTriangles方法
用于生成三角形。通过两层循环,计算每个矩形的两个三角形,并设置Mesh的三角形数组。
private IEnumerator GetTriangles()
{
// 初始化三角形数组
int[] triangles = new int[sequenceX * sequenceY * 6];
int startIndex = 0;
int trianglesIndex = 0;
for (int y = 0; y < sequenceY; y++)
{
for (int x = 0; x < sequenceX; x++)
{
triangles[trianglesIndex] = startIndex;
triangles[trianglesIndex + 1] = startIndex + sequenceX + 1;
triangles[trianglesIndex + 2] = startIndex + 1;
_mesh.triangles = triangles;
yield return new WaitForSeconds(0.2f);
triangles[trianglesIndex + 3] = startIndex + sequenceX + 1;
triangles[trianglesIndex + 4] = startIndex + sequenceX + 2;
triangles[trianglesIndex + 5] = startIndex + 1;
startIndex++;
trianglesIndex += 6;
_mesh.triangles = triangles;
yield return new WaitForSeconds(0.2f);
}
startIndex++;
}
}
OnDrawGizmos方法
用于在Scene视图中绘制顶点的辅助图形,方便调试和观察
private void OnDrawGizmos()
{
if (_vertices == null) return;
for (int i = 0; i < _vertices.Length; i++)
{
// 遍历所有顶点,绘制球形代表每个顶点
Gizmos.DrawSphere(_vertices[i], 0.2f);
}
}
三、效果
四、总结
通过本篇教程,你学会了如何利用Mesh对象在Unity中生成简单的平面,并通过设置顶点、UV坐标和三角形来生成Unity Logo 的效果。