Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

使用 ArrayMesh

本教程将介绍使用 ArrayMesh 的基础知识。

为此,我们将使用函数 add_surface_from_arrays() ,它最多需要五个参数。前两个参数是必须的,后三个参数是可选的。

第一个参数是 PrimitiveType(图元类型),这是 OpenGL 中的概念,用于指示 GPU 如何根据给定的顶点来安排图元,即它们表示的是三角形、线、还是点等等。可选项见 Mesh.PrimitiveType

第二个参数 arrays 是存储网格信息的实际 Array。该数组是一个普通的 Godot 数组,用空括号 [] 构造。它为每一种类型的信息存储一个 Packed**Array(如 PackedVector3Array、PackedInt32Array等),用于构建表面。

arrays 可能包含下列元素,另外还必须在 arrays 中包含位置信息。有关完整列表,另请参阅 Mesh.ArrayType

索引

Mesh.ArrayType 枚举

数组类型

0

ARRAY_VERTEX

PackedVector3ArrayPackedVector2Array

1

ARRAY_NORMAL

PackedVector3Array

2

ARRAY_TANGENT

PackedFloat32ArrayPackedFloat64Array 4 个浮点数组。 前 3 个浮点数确定切线,最后一个浮点数确定副法线方向,即 -1 或 1。

3

ARRAY_COLOR

PackedColorArray

4

ARRAY_TEX_UV

PackedVector2ArrayPackedVector3Array

5

ARRAY_TEX_UV2

PackedVector2ArrayPackedVector3Array

10

ARRAY_BONES

4 个 float 一组的 PackedFloat32Array 或 4 个 int 一组的 PackedInt32Array。每一组都列出了影响某个特定顶点的 4 根骨骼。

11

ARRAY_WEIGHTS

4 个 float 一组的 PackedFloat32ArrayPackedFloat64Array。每个 float 都列出了给定顶点对 ARRAY_BONES 中特定骨骼的权重。

12

ARRAY_INDEX

PackedInt32Array

在大多数情况下,创建网格时,我们通过顶点位置来定义网格。因此,顶点数组(位于索引 0 处)通常是必需的,而索引数组(位于索引 12 处)是可选的,只有在它被包含时才会使用。也可以只创建索引数组而不创建顶点数组,但这超出了本教程的范围。事实上,我们根本不会使用索引数组。

其他所有数组包含的都是关于顶点的信息。它们也是可选的,只有在包含时才会用到。有些数组(例如 ARRAY_COLOR`)用每个顶点一个元素的形式来提供额外的顶点信息。它们的大小必须与顶点数组一致。另一些数组(例如 ARRAY_TANGENT)用四个元素来描述一个顶点。它们必须正好是顶点数组的四倍。

正常的使用场景下,add_surface_from_arrays() 的最后三个参数通常都是留空的。

设置 ArrayMesh

在编辑器中,创建一个 MeshInstance3D ,并在检查器中为其添加一个 ArrayMesh。通常,在编辑器里添加 ArrayMesh 没什么用,但这里可以让我们免去用代码创建的麻烦,直接使用这个 ArrayMesh。

接下来,在 MeshInstance3D 上添加一个脚本。

_ready() 下创建一个新的数组。

var surface_array = []

这将是保存表面信息的数组——将保存表面需要的所有数据数组。Godot 希望它的大小是 Mesh.ARRAY_MAX,所以要相应地调整。

var surface_array = []
surface_array.resize(Mesh.ARRAY_MAX)

接下来, 为你将使用的每种数据类型创建数组.

var verts = PackedVector3Array()
var uvs = PackedVector2Array()
var normals = PackedVector3Array()
var indices = PackedInt32Array()

一旦你用几何体填充了你的数据数组, 就可以通过将每个数组添加到 surface_array , 然后提交到网格中来创建网格.

surface_array[Mesh.ARRAY_VERTEX] = verts
surface_array[Mesh.ARRAY_TEX_UV] = uvs
surface_array[Mesh.ARRAY_NORMAL] = normals
surface_array[Mesh.ARRAY_INDEX] = indices

# No blendshapes, lods, or compression used.
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, surface_array)

备注

在这个例子中,使用了 Mesh.PRIMITIVE_TRIANGLES,但你也可以使用网格所提供的任何图元类型。

把这些放到一起,完整的代码是这样的:

extends MeshInstance3D

func _ready():
    var surface_array = []
    surface_array.resize(Mesh.ARRAY_MAX)