用于通过脚本创建或修改网格的类。
网格包含顶点数据(Positions、Normals、TexCoords 等)和“面”数据,
最常见的面是三角形。
从概念上讲,所有顶点数据都存储在大小相同的单独数组中。例如,如果
一个网格有 100 个顶点,并且希望每个顶点都具有位置、法线和两个
纹理坐标,则该网格应具有 vertices、normals、uv 和 uv2
数组,每个数组的大小都是 100。第 i 个顶点的数据在每个数组中处于索引“i”处。
对于每个顶点,可以具有顶点位置、法线、切线、颜色和最多 8 个纹理坐标。
纹理坐标通常是 2D 数据 (Vector2),但是在需要时可以
将它们设为 Vector3 或 Vector4。这通常用于保存网格顶点中的任意
数据,以及用于着色器中使用的特殊效果。对于蒙皮网格,顶点数据还可以
包含 boneWeights。
网格面数据(即,组成它的三角形)只是每个三角形的三个顶点索引。
例如,如果网格具有 10 个三角形,则 triangles 数组应是 30 个数字,
其中每个数字都指示要使用的顶点。三角形数组中的前三个元素
是组成该三角形的顶点的索引;其次的三个元素组成
另一个三角形,依此类推。
请注意,虽然三角形网格是最常见的用例,不过 Unity 也支持其他
网格拓扑类型,例如线网格或点网格。对于线网格,每条线
由两个顶点索引组成,依此类推。请参阅 SetIndices 和 MeshTopology。
简单与高级网格 API
Mesh 类具有两组方法,可用于从脚本向网格分配数据。“简单”的一组方法为设置索引、三角形、法线、切线等提供基础。这些方法包括验证检查,例如用于确保不会传入包含越界索引的数据。这组方法代表了在 Unity 中从脚本分配网格数据的标准方式。
“简单”方法有:SetColors、SetIndices、SetNormals、SetTangents、SetTriangles、SetUVs、SetVertices、SetBoneWeights
还有一组“高级”方法,通过这些方法可以直接写入网格数据,并控制是否应执行任何检查或验证。这些方法旨在用于需要最大性能的高级用例。它们速度更快,不过允许跳过对提供的数据进行的检查。如果使用这些方法,则必须确保未提供无效数据,因为 Unity 不会进行检查。
“高级”方法有:SetVertexBufferParams、SetVertexBufferData、SetIndexBufferParams、SetIndexBufferData、SetSubMesh,可以使用 Rendering.MeshUpdateFlags 控制是执行还是省略检查或验证。
从脚本操作网格
有三种常见任务可能需要使用网格 API:
1.从头开始构建网格:
应始终按以下顺序进行:
a) 分配 vertices
b) 分配 triangles。
using UnityEngine;
public class Example : MonoBehaviour { Vector3[] newVertices; Vector2[] newUV; 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; } }
bindposes | 绑定姿势。每个索引处的绑定姿势引用索引相同的骨骼。 |
blendShapeCount | 返回此网格上的 BlendShape 计数。 |
boneWeights | 每个顶点的骨骼权重。 |
bounds | 网格的包围体。 |
colors | 网格的顶点颜色。 |
colors32 | 网格的顶点颜色。 |
indexFormat | 网格索引缓冲区数据的格式。 |
isReadable | 如果网格支持读/写,则返回 true,否则返回 false。 |
normals | 网格的法线。 |
subMeshCount | Mesh 对象中的子网格数。 |
tangents | 网格的切线。 |
triangles | 包含网格中所有三角形的数组。 |
uv | 网格的基础纹理坐标。 |
uv2 | 网格的第二个纹理坐标集(如果存在)。 |
uv3 | 网格的第三个纹理坐标集(如果存在)。 |
uv4 | 网格的第四个纹理坐标集(如果存在)。 |
uv5 | 网格的第五个纹理坐标集(如果存在)。 |
uv6 | 网格的第六个纹理坐标集(如果存在)。 |
uv7 | 网格的第七个纹理坐标集(如果存在)。 |
uv8 | 网格的第八个纹理坐标集(如果存在)。 |
vertexBufferCount | 获取网格中存在的顶点缓冲区数。(只读) |
vertexCount | 返回网格中的顶点数(只读)。 |
vertices | 返回顶点位置的副本或分配新顶点位置数组。 |
Mesh | 创建空网格。 |
AddBlendShapeFrame | 添加新的混合形状帧。 |
Clear | 清除所有顶点数据和所有三角形索引。 |
ClearBlendShapes | 从网格中清除所有混合形状。 |
CombineMeshes | 将多个网格合并到此网格中。 |
GetBaseVertex | 获取给定 sub-mesh 的基顶点索引。 |
GetBindposes | 获取网格的绑定姿势。 |
GetBlendShapeFrameCount | 返回混合形状的帧计数。 |
GetBlendShapeFrameVertices | 检索混合形状帧的 deltaNormals、deltaNormals 和 /deltaTangents/。 |
GetBlendShapeFrameWeight | 返回混合形状帧的权重。 |
GetBlendShapeIndex | 按给定名称返回 BlendShape 的索引。 |
GetBlendShapeName | 按给定索引返回 BlendShape 的名称。 |
GetBoneWeights | Gets the bone weights of the Mesh. |
GetColors | 获取网格的顶点颜色。 |
GetIndexCount | 获取给定 sub-mesh 的索引计数。 |
GetIndexStart | 对于给定 /sub-mesh/,获取网格索引缓冲区中的起始索引位置。 |
GetIndices | 获取指定子网格的索引列表。 |
GetNativeIndexBufferPtr | 检索指向索引缓冲区的原生(底层图形 API)指针。 |
GetNativeVertexBufferPtr | 检索指向顶点缓冲区的原生(底层图形 API)指针。 |
GetNormals | 获取网格的顶点法线。 |
GetTangents | 获取网格的切线。 |
GetTopology | 获取子网格的拓扑。 |
GetTriangles | 获取此对象上指定子网格的切线列表。 |
GetUVDistributionMetric | UV 分布指标可用于根据摄像机的位置计算所需的 Mipmap 级别。 |
GetUVs | 获取网格的 UV。 |
GetVertices | 获取网格的顶点位置。 |
MarkDynamic | 优化网格以便频繁更新。 |
RecalculateBounds | 从顶点重新计算网格的包围体。 |
RecalculateNormals | 从三角形和顶点重新计算网格的法线。 |
RecalculateTangents | 从法线和纹理坐标重新计算网格的切线。 |
SetColors | 设置网格的每顶点颜色。 |
SetIndices | 为子网格设置索引缓冲区。 |
SetNormals | 设置网格的法线。 |
SetTangents | 设置网格的切线。 |
SetTriangles | 为子网格设置三角形列表。 |
SetUVs | 设置网格的 UV。 |
SetVertices | 分配新的顶点位置数组。 |
UploadMeshData | 将以前进行的网格修改上传到图形 API。 |
GetInstanceID | 返回对象的实例 ID。 |
ToString | 返回对象的名称。 |
Destroy | 移除 GameObject、组件或资源。 |
DestroyImmediate | 立即销毁对象 /obj/。强烈建议您改用 Destroy。 |
DontDestroyOnLoad | 在加载新的 Scene 时,请勿销毁 Object。 |
FindObjectOfType | 返回第一个类型为 type 的已加载的激活对象。 |
FindObjectsOfType | 返回所有类型为 type 的已加载的激活对象的列表。 |
Instantiate | 克隆 original 对象并返回克隆对象。 |
bool | 该对象是否存在? |
operator != | 比较两个对象是否引用不同的对象。 |
operator == | 比较两个对象引用,判断它们是否引用同一个对象。 |