导入3D场景

Godot 场景导入器

在处理 3D 素材时,Godot 有一个非常灵活且可配置的导入器。

Godot 使用 场景 工作。这意味着用您最喜爱的3D软件制作的整个场景可以尽可能完整地被导入。

Godot支持以下 3D 场景文件格式

  • glTF 2.0. Godot has full support for text and binary formats.
  • DAE (COLLADA):一个比较老的格式,当然完全支持。
  • OBJ(Wavefront)格式。它也得到完全支持,但是非常有限(不支持枢轴、骨架等)。
  • ESCN,Blender可以通过插件导出的,一种Godot特定格式。
  • FBX, supported via the Open Asset Import library. However, FBX is proprietary, so we recommend using other formats listed above, if suitable for your workflow.

只需将场景文件和纹理一起复制到项目存储库中,Godot 就可以完全导入。

在输出时,网格不会被骨骼变形很重要。在使用您喜欢的3D编辑器进行导出之前,请确保将骨骼重置为其T姿势或默认的静止姿势。

从Maya和3DS Max导出的DAE文件

Autodesk 为 Maya 和 3DS Max添加了内置的 COLLADA 支持,但默认情况下已损坏,因此不应使用。导出此格式的最佳方法是使用 OpenCollada 插件。尽管它们并非总是与最新版本的软件保持一致,但它们可以很好地工作。

从Blender导出glTF 2.0文件

有三种方法可以从Blender导出glTF文件。作为一个glTF二进制文件(.glb 文件)、嵌入的glTF(.gltf 文件)、和使用纹理(gltf + .bin + 纹理)。

glTF二进制文件是三个选项中最小的一个。它们包括在Blender中设置的网格和纹理。当放入Godot中时,纹理将成为对象材质文件的一部分。

glTF嵌入式文件的功能与二进制文件相同。它们没有在Godot中提供额外的功能,也不应使用,因为它们的文件较大。

将glTF与纹理分开使用有两个原因。一种是将场景以基于文本的格式和二进制数据,描述在单独的二进制文件中。这对于版本控制很有用,如果要基于文本格式评审更改。第二种是您需要将纹理文件与材质文件分开。如果您不需要这些glTF二进制文件的任一个,也可以。

注解

Blender does not export emissive textures with the glTF file. If your model uses one, it must be brought in separately.

从Blender导出的DAE文件

Blender也有内置的 COLLADA 支持,但不能满足游戏引擎的需求,不能完全正常工作,不应该使用。

Godot provides a Blender plugin that will correctly export COLLADA scenes for use in Godot. It does not work in Blender 2.8 or newer, but there are plans to update it in the future.

从Blender导出ESCN文件

The most powerful one, called godot-blender-exporter. It uses a .escn file, which is kind of another name for a .tscn file (Godot scene file); it keeps as much information as possible from a Blender scene. However, it is considered experimental.

ESCN导出器有一个详细的 文档 ,描述了它的功能和用法。

导入工作流程

Godot场景导入器允许有关如何导入数据的不同工作流。根据许多选项,可以通过以下方式导入场景:

  • 外部材质(默认):将每种材质保存到文件资源的位置。保留对它们的修改。
  • 外部网格:每个网格被保存到不同文件的位置。许多用户喜欢直接处理网格。
  • 外部动画:允许在源更改时,修改和合并保存的动画。
  • 外部场景:将每个导入场景的根节点保存为单独的场景。
  • 单场景:内置所有内容的单场景文件。
../../../_images/scene_import1.png

由于不同的开发人员有不同的需求,因此此导入过程是高度可定制的。

导入选项

导入器有几种选项,这将在下面讨论:

../../../_images/scene_import2.png

节点

根类型

默认情况下,导入场景中根节点的类型为 Spatial,但是可以对其进行修改。

根名称

允许为生成的根节点设置特定名称。

根规模

根节点的规模。

自定义脚本

可以提供一个特殊脚本,来处理导入后的整个场景。这非常适合后期处理、更换材质、对几何图形做有趣的事情等。

创建如下的脚本:

tool # Needed so it runs in the editor.
extends EditorScenePostImport


func post_import(scene):
    # Do your stuff here.
    return scene # remember to return the imported scene

post_import 函数将导入的场景作为参数(参数实际上是场景的根节点)。必须返回最终将要使用的场景。它可以是不同的。

存储

默认情况下,Godot导入一个单独的场景。此选项允许指定根下面的节点将是一个单独的场景,并被实例化到导入的场景中。

当然,在其他地方手动实例导入的场景也是可以的。

材质

位置

Godot 支持网格或节点中的材质。默认情况下,材质将放置在每个节点上。

存储

材质可以存储在场景中或外部文件中。默认情况下,它们存储在外部文件中,因此可以进行编辑。这是因为大多数 3D 数字创作软件没有与 Godot 中的相同的材质选项。

当材质是内置的时,每当源场景被修改并重新导入时,它们都会丢失。

注解

Godot will not reimport materials that are stored in external files unless you remove the associated .material file before reimporting.

To force reimporting materials every time the 3D scene is reimported, change the material storage mode in the 3D scene by selecting it in the FileSystem dock, going to the Import dock then setting Material > Storage to Built-In instead of Files.

保持开启重新导入

一旦将材质编辑为使用Godot功能,导入器将保留已编辑的材质,并忽略来自源场景的材料。仅当材质保存为文件时,此选项才存在。

网格

压缩

使网格对网格的多个方面使用不太精确的数字以节省空间。

这些是:
  • 变换矩阵(位置、旋转、和缩放):32位浮点数到16位有符号整数。
  • 顶点:32 位浮点数到16位有符号整数。
  • 法线:32 位浮点数到32位无符号整数。
  • 切线:32 位浮点数到32位无符号整数。
  • 顶点色:32 位浮点数到32位无符号整数。
  • UV:32 位浮点数到32位无符号整数。
  • UV2:32 位浮点数到32位无符号整数。
  • 顶点权重:32 位浮点数到32位无符号整数。
  • 骨架骨骼:32 位浮点数到16位无符号整数。
  • 数组索引:基于具体有多少元素,32位或16位无符号整数。
附加信息:
  • UV2 = 用于细节纹理和烘焙光照纹理的第二个 UV 通道。
  • 数组索引 = 一个数字数组,它为上面数组的每个元素计数;即, 它们的顶点和法线的数量。

在某些情况下,这可能会导致精度损失,因此可能需要禁用此选项。例如,如果网格非常大或导入了多个网格覆盖巨大的区域,则压缩此网格的导入,可能会导致几何图形的间隙、或顶点不在它们应在的位置。

确保切线

如果要使用法线贴图的纹理,网格需要有切线阵列。此选项可确保如果这些阵列在源场景中不存在,则生成它们。Godot 使用 Mikktspace 来做这件事,但最好让它们在导出器中生成。

存储

网格可以存储在单独的文件(资源)中,而不是内置的。除非有人想直接用它们建立对象,否则这没有多少实际用途。

提供此选项是为了帮助那些喜欢直接使用网格而不是场景的人。

光线烘焙

网格是否用于烘焙光照贴图中。

  • 禁用: 网格未用于烘焙的光照贴图中。
  • 启用: 网格用于烘焙的光照贴图中。
  • Gen光照贴图: 网格用于烘焙光照贴图中,并为光照贴图展开第二个UV层。

注解

有关光线烘焙的更多信息,请参阅 烘焙光照贴图

外部文件

生成的网格和材质可以选择存储在具有场景名称的子目录中。

动画选项

Godot提供了许多有关如何处理动画数据的选项。一些导出器(如Blender)可以在一个文件中生成许多动画。其他的,如3DS Max 或 Maya,需要将许多动画放入同一时间线,或者最糟糕的情况是将每个动画放在单独的文件中。

../../../_images/scene_import3.png

默认情况下启用动画导入。

FPS

大多数3D导出格式都以秒而不是帧的形式存储动画时间轴。为确保尽可能真实地导入动画,请指定用于编辑动画的每秒帧数。未能这么做,可能会导致动画不稳定。

过滤器脚本

可以使用特殊语法指定过滤器脚本,以决定应保留哪些动画的哪些轨道。

The filter script is executed against each imported animation. The syntax consists of two types of statements, the first for choosing which animations to filter, and the second for filtering individual tracks within the matched animation. All name patterns are performed using a case insensitive expression match, using ? and * wildcards (using String.matchn() under the hood).

The script must start with an animation filter statement (as denoted by the line beginning with an @). For example, if we would like to apply filters to all imported animations which have a name ending in "_Loop":

@+*_Loop

Similarly, additional patterns can be added to the same line, separated by commas. Here is a modified example to additionally include all animations with names that begin with "Arm_Left", but also exclude all animations which have names ending in "Attack":

@+*_Loop, +Arm_Left*, -*Attack

Following the animation selection filter statement, we add track filtering patterns to indicate which animation tracks should be kept or discarded. If no track filter patterns are specified, then all tracks within the matched animations will be discarded!

It's important to note that track filter statements are applied in order for each track within the animation, this means that one line may include a track, a later rule can still discard it. Similarly, a track excluded by an early rule may then be re-included once again by a filter rule further down in the filter script.

For example: include all tracks in animations with names ending in "_Loop", but discard any tracks affecting a "Skeleton" which end in "Control", unless they have "Arm" in their name:

@+*_Loop
+*
-Skeleton:*Control
+*Arm*

In the above example, tracks like "Skeleton:Leg_Control" would be discarded, while tracks such as "Skeleton:Head" or "Skeleton:Arm_Left_Control" would be retained.

Any track filter lines that do not begin with a + or - are ignored.

存储

默认情况下,动画保存为内置。可以将它们保存到一个文件中。这允许向动画添加自定义轨道并在重新导入后保留它们。

优化

导入动画时,会运行优化程序,从而大大减少动画的大小。一般情况下,除非您怀疑动画可能因启用而被破坏,否则应始终启用此功能。

剪辑

It is possible to specify multiple animations from a single timeline as clips. For this to work, the model must have only one animation that is named default. To create clips, change the clip amount to something greater than zero. You can then name a clip, specify which frames it starts and stops on, and choose whether the animation loops or not.

场景继承

在许多情况下,可能需要对导入的场景进行修改。默认情况下,这是不可能的,因为如果源素材发生更改(从3D建模应用程序重新导出了源 .dae.gltf.obj),Godot将重新导入 整个场景。

但是,可以使用 场景继承 进行本地修改。尝试打开导入的场景,将出现以下对话框:

../../../_images/scene_import4.png

在继承场景中,修改的唯一限制是:

  • 无法删除节点(但可以在任何位置添加)。
  • 子资源无法被编辑(如上所述它们将保存在外部)

除此之外,一切都是允许的!

导入提示

很多时候,编辑场景时,导出后需要完成一些常见任务:

  • Adding collision detection to objects.
  • Setting objects as navigation meshes.
  • Deleting nodes that are not used in the game engine (like specific lights used for modelling).

To simplify this workflow, Godot offers several suffixes that can be added to the names of the objects in your 3D modelling software. When imported, Godot will detect suffixes in object names and will perform actions automatically.

注解

All the suffixes described below are case-sensitive.

删除节点(-noimp

Objects that have the -noimp suffix will be removed at import-time no matter what their type is. They will not appear in the imported scene.

Create collisions (-col, -convcol, -colonly, -convcolonly)

The option -col will work only for Mesh objects. If it is detected, a child static collision node will be added, using the same geometry as the mesh. This will create a triangle mesh collision shape, which is a slow, but accurate option for collision detection. This option is usually what you want for level geometry (but see also -colonly below).

The option -convcol will create a ConvexPolygonShape instead of a ConcavePolygonShape. Unlike triangle meshes which can be concave, a convex shape can only accurately represent a shape that doesn't have any concave angles (a pyramid is convex, but a hollow box is concave). Due to this, convex collision shapes are generally not suited for level geometry. When representing simple enough meshes, convex collision shapes can result in better performance compared to a triangle collision shape. This option is ideal for simple or dynamic objects that require mostly-accurate collision detection.

However, in both cases, the visual geometry may be too complex or not smooth enough for collisions. This can create physics glitches and slow down the engine unneccesarily.

To solve this, the -colonly modifier exists. It will remove the mesh upon importing and will create a StaticBody collision instead. This helps the visual mesh and actual collision to be separated.

The option -convcolonly works in a similar way, but will create a ConvexPolygonShape instead.

The option -colonly can also be used with Blender's empty objects. On import, it will create a StaticBody with a collision node as a child. The collision node will have one of a number of predefined shapes, depending on Blender's empty draw type:

../../../_images/3dimp_BlenderEmptyDrawTypes.png

When possible, try to use a few primitive collision shapes instead of triangle mesh or convex shapes. Primitive shapes often have the best performance and reliability.

注解

For better visibility in Blender's editor, you can set the "X-Ray" option on collision empties and set some distinct color for them in Blender's User Preferences > Themes > 3D View > Empty.

参见

See Collision shapes (3D) for a comprehensive overview of collision shapes.

创建导航(-navmesh

A mesh node with the -navmesh suffix will be converted to a navigation mesh. The original Mesh object will be removed at import-time.

创建一个 VehicleBody-vehicle

A mesh node with the -vehicle suffix will be imported as a child to a VehicleBody node.

创建一个 VehicleWheel-wheel

A mesh node with the -wheel suffix will be imported as a child to a VehicleWheel node.

刚体(-rigid

A mesh node with the -rigid suffix will be imported as a RigidBody.

动画循环(-loop-cycle

Animation clips in the COLLADA document that start or end with the token loop or cycle will be imported as a Godot Animation with the loop flag set. Unlike the other suffixes described above, this does not require a hyphen.

In Blender, this requires using the NLA Editor and naming the Action with the loop or cycle prefix or suffix.