版本 : 2019.3
官方文档传送门
Mesh是UnityEngine命名空间下的一个类.
描述 :
一个允许通过脚本创建或修改网格的类。
网格包含顶点数据(位置,法线,纹理坐标等)和面(面通常是三角形)数据。
从概念上讲,所有顶点数据都存储在相同大小的单独数组中。例如,如果您有一个包含100个顶点的网格,并且希望每个顶点具有一个位置,法线和两个纹理坐标,则该网格应具有顶点,法线,uv和uv2 数组,每个数组的大小为100。第i个顶点的数据在每个数组中的索引为“ i”。
对于每个顶点,可以有一个顶点位置,法线,切线,颜色和最多8个纹理坐标。纹理坐标通常是2D数据(Vector2),但可以将其设置为 Vector3或Vector4(如果需要)。最常用于在网格顶点中保存任意数据,以用于着色器中的特殊效果。对于蒙皮的网格,顶点数据也可以包含boneWeights。
网格面数据(即由其构成的三角形)只是每个三角形的三个顶点索引。例如,如果网格具有10个三角形,则三角形数组应为30个数字,每个数字指示要使用的顶点。三角形数组中的前三个元素是构成该三角形的顶点的索引。后三个元素组成另一个三角形,依此类推。
请注意,虽然三角形网格是最常见的用例,但Unity还支持其他网格拓扑类型,例如线或点网格。对于线网格,每条线由两个顶点索引组成,依此类推。请参见SetIndices和MeshTopology。
简单与高级Mesh API
Mesh类有两组方法,用于从脚本向Mesh分配数据。“简单”的方法集为设置索引,三角形,法线,切线等提供了基础。这些方法包括验证检查,例如,确保您不会传递包含越界索引的数据。它们代表从Unity中的脚本分配网格数据的标准方法。
“简单”的方法有:SetColors,SetIndices,SetNormals,SetTangents,SetTriangles,SetUVs,SetVertices,SetBoneWeights
还有一组“高级”方法,使您可以控制是否应执行任何检查或验证来直接写入网格数据。这些方法适用于需要最高性能的高级用例。它们速度更快,但是可以让您跳过对所提供数据的检查。如果使用这些方法,则必须确保您没有提供无效的数据,因为Unity不会检查您。
“高级”方法是:SetVertexBufferParams,SetVertexBufferData,SetIndexBufferParams,SetIndexBufferData,SetSubMesh,您可以使用MeshUpdateFlags来控制执行或省略哪些检查或验证。
(简单的说的话 : 简单方法会有数组越界等数据验证检查,
高级方法不会进行数据验证但速度更快)
通过脚本操作网格
可能需要使用Mesh API进行以下三个常见任务:
1.从头开始构建网格:应始终按以下顺序进行:
a)分配顶点(vertex)
b)分配三角形(triangle)
using UnityEngine;
public class Example : MonoBehaviour
{
Vector3[] newVertices; //顶点
Vector2[] newUV; //UV坐标
int[] newTriangles; //三角形
void Start()
{
Mesh mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
mesh.vertices = newVertices;
mesh.uv = newUV;
mesh.triangles = newTriangles;
}
}
2.每一帧修改顶点属性:
a)获取顶点
b)修改顶点
c)将它们分配回网格。
using UnityEngine;
public class Example : MonoBehaviour
{
void Update()
{
Mesh mesh = GetComponent<MeshFilter>().mesh;
Vector3[] vertices = mesh.vertices;
Vector3[] normals = mesh.normals;
for (var i = 0; i < vertices.Length; i++)
{
vertices[i] += normals[i] * Mathf.Sin(Time.time);
}
mesh.vertices = vertices;
}
}
3.连续更改网格的三角形和顶点:
a)调用Clear()来清除数据
b)分配顶点和其他属性
c)分配三角形索引。在分配新的顶点或三角形之前,请先调用Clear()。Unity始终检查提供的三角形索引是否没有引用超出范围的顶点。调用Clear(),然后分配顶点,再分配三角形,以确保您永远不会出界数据。
using UnityEngine;
public class ExampleClass : MonoBehaviour
{
Vector3[] newVertices;
Vector2[] newUV;
int[] newTriangles;
void Start()
{
Mesh mesh = GetComponent<MeshFilter>().mesh;
mesh.Clear();
// Do some calculations...
mesh.vertices = newVertices;
mesh.uv = newUV;
mesh.triangles = newTriangles;
}
}
接下来的属性,方法等,我挑常用的写,其他方法可以看官方API
属性 :
属性名 | 描述 |
---|---|
bounds | 网格物体的边界体积。 |
colors | 网格的顶点颜色。 |
normals | 网格的法线。 |
tangents | 网格的切线。 |
triangles | 包含网格中所有三角形的数组。 |
uv | 网格的基本纹理坐标。 |
vertexCount | 网格中的顶点数(只读) |
vertex | 返回顶点位置的副本或分配一个新的顶点位置数组。 |
公有方法 :
方法名 | 描述 |
---|---|
Clear | 清除所有顶点数据和所有三角形索引。 |
CombineMeshes | 将多个网格合并到该网格中。 |
GetColors | 获取网格的顶点颜色。 |
GetNormals | 获取网格的顶点法线。 |
GetTangents | 获取网格的切线。 |
GetTriangles | 获取此对象上指定子网格的三角形列表。 |
GetUVs | 获取网格的UV。 |
GetVertexAttribute | 获取有关网格的顶点属性的信息。 |
GetVertices | 获取网格的顶点位置。 |
RecalculateBounds | 从顶点重新计算网格物体的边界体积。 |
RecalculateNormals | 从三角形和顶点重新计算网格的法线。 |
RecalculateTangents | 根据法线和纹理坐标重新计算网格的切线。 |
SetColors | 设置顶点颜色 |
SetNormals | 设置网格法线 |
SetTangents | 设置网格的切线。 |
SetTriangles | 设置子网格的三角形列表。 |
SetUVs | 设置网格的UV。 |
SetVertices | 分配一个新的顶点位置数组。 |