版本: Unity 6 (6000.0)
语言英语
  • C#

MeshData

UnityEngine 中的结构体

/

实现于:UnityEngine.CoreModule

建议更改

成功!

感谢您帮助我们提高 Unity 文档的质量。虽然我们无法接受所有提交,但我们会阅读用户提出的每个建议更改,并在适用时进行更新。

关闭

提交失败

由于某些原因,您的建议更改无法提交。请<a>稍后再试</a>。感谢您抽出时间帮助我们提高 Unity 文档的质量。

关闭

取消

切换到手册

描述

包含用于 C# Job System 访问的网格数据的结构体。

使用 MeshData 结构体在 C# Job System 中访问、处理和创建网格。有两种类型的 MeshData 结构体:只读 MeshData 结构体,允许从 C# Job System 读取网格数据;可写 MeshData 结构体,允许您从 C# Job System 创建网格。

只读 MeshData

当您将一个或多个网格传递给 Mesh.AcquireReadOnlyMeshData 时,Unity 会返回一个包含只读 MeshData 结构体的 MeshDataArray。您可以从任何线程访问生成的 MeshDataArrayMeshData 结构体。出于内存跟踪和安全原因,创建 MeshDataArray 会产生一些开销,因此,最好只调用一次 Mesh.AcquireReadOnlyMeshData 并请求同一个 MeshDataArray 中的多个 MeshData 结构体,而不是多次调用 Mesh.AcquireReadOnlyMeshData

每个 MeshData 结构体都包含给定网格的数据的只读快照。您可以使用 GetIndexDataGetVertexData 访问原始的只读网格数据,而无需任何内存分配、数据复制或格式转换。您需要了解确切的网格数据布局才能执行此操作:例如,所有网格顶点属性的存在和格式。您可以使用 GetColorsGetIndicesGetNormalsGetTangentsGetUVsGetVertices 将只读网格数据复制到预先存在的数组中。这些方法还根据需要执行数据格式转换。例如,如果只读 MeshData 结构体使用 VertexAttributeFormat.Float16 法线,并且您调用 GetNormals,则法线将转换为目标数组中的 Vector3 法线。

完成对 MeshDataArray 的操作后,必须将其释放。只要您在修改网格之前释放了 MeshDataArray,默认情况下,调用 Mesh.AcquireReadOnlyMeshData 不会导致任何内存分配或数据复制。但是,如果您调用 Mesh.AcquireReadOnlyMeshData,然后在 MeshDataArray 存在时修改网格,则 Unity 必须将 MeshDataArray 复制到新的内存分配中。此外,如果您调用 Mesh.AcquireReadOnlyMeshData,然后修改网格,则您的修改不会反映在 MeshData 结构体中。

使用 Dispose 释放 MeshDataArray,或者使用 C# using 模式自动执行此操作。

using Unity.Collections;
using UnityEngine;
public class ExampleScript : MonoBehaviour
{
    void Start()
    {
        var mesh = new Mesh();
        mesh.vertices = new[] {Vector3.one, Vector3.zero};
        using (var dataArray = Mesh.AcquireReadOnlyMeshData(mesh))
        {
            var data = dataArray[0];
            // prints "2"
            Debug.Log(data.vertexCount);
            var gotVertices = new NativeArray<Vector3>(mesh.vertexCount, Allocator.TempJob);
            data.GetVertices(gotVertices);
            // prints "(1.0, 1.0, 1.0)" and "(0.0, 0.0, 0.0)"
            foreach (var v in gotVertices)
                Debug.Log(v);
            gotVertices.Dispose();
        }
    }
}

可写 MeshData

使用 Mesh.AllocateWritableMeshData 获取一个包含可写 MeshData 结构体的 MeshDataArray。您可以从任何线程访问生成的 MeshDataArrayMeshData 结构体。出于内存跟踪和安全原因,创建 MeshDataArray 会产生一些开销,因此,最好只调用一次 Mesh.AllocateWritableMeshData 并请求同一个 MeshDataArray 中的多个 MeshData 结构体,而不是多次调用 Mesh.AllocateWritableMeshData

您可以使用数据填充可写 MeshData 结构体以创建新的网格。使用 Mesh.MeshData.SetVertexBufferParams 设置顶点缓冲区大小和布局,然后写入 Mesh.MeshData.GetVertexData 返回的数组以设置顶点。使用 Mesh.MeshData.SetIndexBufferParams 设置索引缓冲区大小和格式,然后写入 Mesh.MeshData.GetIndexData 返回的数组以设置索引。写入 Mesh.MeshData.subMeshCount 以设置子网格的数量,然后使用 Mesh.MeshData.SetSubMesh 设置子网格数据。

使用数据填充可写 MeshData 结构体后,使用 Mesh.ApplyAndDisposeWritableMeshData 将数据应用于 Mesh 对象并自动释放 MeshDataArray

using UnityEngine;
using UnityEngine.Rendering;
using Unity.Collections;

[RequireComponent(typeof(MeshFilter))] public class ExampleScript : MonoBehaviour { void Start() { // Allocate mesh data for one mesh. var dataArray = Mesh.AllocateWritableMeshData(1); var data = dataArray[0];

// Tetrahedron vertices with positions and normals. // 4 faces with 3 unique vertices in each -- the faces // don't share the vertices since normals have to be // different for each face. data.SetVertexBufferParams(12, new VertexAttributeDescriptor(VertexAttribute.Position), new VertexAttributeDescriptor(VertexAttribute.Normal, stream: 1));

// Four tetrahedron vertex positions: var sqrt075 = Mathf.Sqrt(0.75f); var p0 = new Vector3(0, 0, 0); var p1 = new Vector3(1, 0, 0); var p2 = new Vector3(0.5f, 0, sqrt075); var p3 = new Vector3(0.5f, sqrt075, sqrt075 / 3);

// The first vertex buffer data stream is just positions; // fill them in. NativeArray<Vector3> pos = data.GetVertexData<Vector3>(); pos[0] = p0; pos[1] = p1; pos[2] = p2; pos[3] = p0; pos[4] = p2; pos[5] = p3; pos[6] = p2; pos[7] = p1; pos[8] = p3; pos[9] = p0; pos[10] = p3; pos[11] = p1;

// Note: normals will be calculated later in RecalculateNormals. // Tetrahedron index buffer: 4 triangles, 3 indices per triangle. // All vertices are unique so the index buffer is just a // 0,1,2,...,11 sequence. data.SetIndexBufferParams(12, IndexFormat.UInt16); NativeArray<ushort> indexBuffer = data.GetIndexData<ushort>(); for (ushort i = 0; i < indexBuffer.Length; ++i) indexBuffer[i] = i;

// One sub-mesh with all the indices. data.subMeshCount = 1; data.SetSubMesh(0, new SubMeshDescriptor(0, indexBuffer.Length)); // Create the mesh and apply data to it: var mesh = new Mesh(); mesh.name = "Tetrahedron"; Mesh.ApplyAndDisposeWritableMeshData(dataArray, mesh); mesh.RecalculateNormals(); mesh.RecalculateBounds(); GetComponent<MeshFilter>().mesh = mesh; } }

属性

indexFormat获取 MeshData 中索引缓冲区数据的格式。(只读)
subMeshCountMeshData 中子网格的数量。
vertexBufferCount获取 MeshData 中顶点缓冲区的数量。(只读)
vertexCount获取 MeshData 中顶点的数量。(只读)

公共方法

GetColors使用 MeshData 中的顶点颜色填充数组。
GetIndexData获取 MeshData 的索引缓冲区的原始数据。
GetIndices使用 MeshData 中给定子网格的索引填充数组。
GetNormals使用 MeshData 中的顶点法线填充数组。
GetSubMesh获取 MeshData 中给定子网格的数据。
GetTangents使用 MeshData 中的顶点切线填充数组。
GetUVs使用 MeshData 中的 UV 填充数组。
GetVertexAttributeDimension获取 MeshData 中给定顶点属性的维度。
GetVertexAttributeFormat获取 MeshData 中给定顶点属性的格式。
GetVertexAttributeOffset获取此 MeshData 上给定顶点数据属性在顶点缓冲区流中的偏移量。
GetVertexAttributeStream获取此 MeshData 上特定顶点数据属性的顶点缓冲区流索引。
GetVertexBufferStride获取顶点缓冲区流的跨度(以字节为单位)。
GetVertexData获取 MeshData 中给定顶点缓冲区流格式的原始数据。
GetVertices使用 MeshData 中的顶点位置填充数组。
HasVertexAttribute检查 MeshData 中是否存在给定的顶点属性。
SetIndexBufferParams设置 Unity 从 MeshData 创建的网格的索引缓冲区大小和格式。
SetSubMesh设置 Unity 从 MeshData 创建的网格的子网格的数据。
SetVertexBufferParams设置 Unity 从 MeshData 创建的网格的顶点缓冲区大小和布局。