Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

导入配置

Godot提供了多种自定义导入数据的方法,比如导入面板、高级导入设置对话框和继承场景。这些功能可以用来对导入的场景进行进一步的更改,比如调整网格、添加物理信息和添加新节点。你还可以编写一个脚本,在导入过程结束时运行代码,以执行任意的自定义操作。

请注意,在适用的情况下,应该优先修改原始数据,而不是导入后再配置场景。这有助于最大程度减少 3D 建模软件与实际导入场景之间的差异。可参考 导出模型的注意事项使用名称后缀自定义节点类型 来获取更多信息。

导入工作流程

由于 Godot 只能保存自己的场景格式(.tscn/.scn),Godot 无法覆盖原始的 3D 场景文件(后者采用不同的格式)。这也是一种更安全的做法,可以避免意外更改源文件。

为了允许自定义场景及其材质,Godot 的场景导入器针对数据的导入方式提供了不同的工作流程。

在文件系统面板中选择 3D 场景后的导入面板

在文件系统面板中选择 3D 场景后的导入面板

这个导入过程可以通过 3 个单独的界面进行自定义,具体取决于你的需求:

  • 导入面板:在文件系统面板中单击选中 3D 场景后即可使用。

  • 高级导入设置对话框:在文件系统面板中双击 3D 场景,或者在导入面板中点击高级按钮来打开。这允许你在 Godot 中自定义每个物体的选项,并预览模型和动画。可参考高级导入设置来获取更多信息。

  • 使用名称后缀自定义节点类型:在 3D 建模软件中,添加到对象名称后的特殊后缀。这允许你在 3D 建模软件中自定义每个对象的选项。

对于基本的自定义,使用导入面板就足够了。然而,对于更复杂的操作(例如基于每种材质定义材质覆盖),你需要使用高级导入设置对话框、导入提示,或者两者结合使用。

使用导入面板

在文件系统面板选中一个 3D 场景之后,可以在导入面板中调整以下选项:

  • 根类型:用作根节点的节点类型。建议使用继承自 Node3D 的节点类型。否则,你将无法直接在 3D 编辑器中设置该节点的位置。

  • 根名称:导入场景中根节点的名称。在编辑器中实例化场景(或从文件系统面板拖放)时,通常不会注意到该名称,因为根节点在这种情况下会被重命名为与文件名一致。

  • 应用根缩放:如果启用,根缩放将直接应用于网格和动画,同时保持根节点的缩放为默认值 (1, 1, 1) 。这意味着如果你稍后在导入的场景中添加一个子节点,该子节点不会被缩放。如果禁用,根缩放将乘以根节点的缩放。

网格

  • 确保切线:如果勾选,在导入的网格没有提供切线数据时,将会使用 Mikktspace 生成顶点的切线。如果可能,推荐使用 3D 建模软件在导出时生成切线,而不是依赖此选项。正确显示法线和高度贴图以及任何需要切线的材质/着色器功能都需要切线。如果你不需要依赖切线的材质功能,并且在源 3D 文件中不包含切线的情况下,禁用此选项可以减少输出文件的大小并加快导入速度。

  • 生成 LOD:如果勾选,则会生成网格的低细节变体,这些变体将在远处显示以提高渲染性能。并非所有网格体都会受益于 LOD,特别是那些永远不会从远处渲染的网格。禁用此选项可以减少输出文件大小并加快导入速度。请参阅网格的细节级别(LOD)了解更多信息。

  • 创建阴影网格:如果勾选,则在导入时生成阴影网格。通过合并可能的顶点,这能够在不降低质量的前提下优化阴影渲染。这反过来又减少了渲染阴影所需的内存带宽。阴影网格生成当前不支持使用比源网格更低的细节级别(但阴影渲染在相关情况下会使用 LOD)。

  • 光照烘焙:配置 3D 场景中网格的全局光照模式。如果设置为 Static Lightmaps(静态光照贴图),则将网格的 GI 模式设置为 Static(静态)并在导入时为烘焙光照贴图生成 UV2。

  • 光照贴图纹素大小:仅当光照烘焙设置为 Static Lightmaps 时可见。用来控制烘焙光照贴图上每个纹素的大小。较小的值会产生更精确的光照贴图,但代价是光照贴图大小更大、烘焙时间更长。

蒙皮

  • 使用具名蒙皮:如果勾选,则为动画使用命名的蒙皮MeshInstance3D节点包含 3 个相关属性:指向 Skeleton3D 节点的骨骼 NodePath(通常为 .. )、一个网格和一个蒙皮:

    • Skeleton3D节点包含一个命名的骨骼列表,其中每个骨骼包含姿势、放松姿势、名称和父骨骼。

    • 网格是显示网格所需的所有原始顶点数据。就网格而言,它知道如何对顶点进行加权绘制,并使用通常从 3D 建模软件导入的内部编号。

    • 蒙皮包含将此网格物体绑定到此 Skeleton3D 上所需的信息。对于 3D 建模软件选择的每一个内部骨骼 ID,它都包含两个内容。首先,一个矩阵,称为绑定姿势矩阵(Bind Pose Matrix)、逆绑定矩阵(Inverse Bind Matrix),或简称 IBM。其次,蒙皮包含每个骨骼的名称(如果启用使用具名蒙皮选项),或者骨骼在 Skeleton3D 列表中的索引(如果禁用了使用具名蒙皮选项)。

这些信息共同足以告诉 Godot 如何使用 Skeleton3D 节点中的骨骼姿势来渲染每个 MeshInstance3D 中的网格。请注意,MeshInstance3D 之间可能共享绑定(这在从 Blender 导出的模型中很常见);或者每个 MeshInstance3D 可能都使用单独的蒙皮对象(这在从其他工具(如 Maya)导出的模型中很常见)。

动画

  • 导入:如果勾选,则从 3D 场景导入动画。

  • FPS:用线性插值将动画曲线烘焙为一系列点时使用的每秒帧数。建议将此值设置为与你在 3D 建模软件中使用的基准值相匹配。数值越大,动画在快速运动变化时越精确,但代价是文件大小和内存使用量也越大。由于插值的存在,超过 30 FPS 通常不会有太大好处(因为动画在更高的渲染帧率下仍会显得平滑)。

  • 修剪:如果没有关键帧变化,则修剪动画的开头和结尾。这可以根据动画轨道的内容,减少某些 3D 场景的输出文件大小和内存使用量。

  • 移除不可修改的轨道:移除只包含默认值的动画轨道。这可以根据动画轨道的内容,减少某些 3D 场景的输出文件大小和内存使用量。

导入脚本

  • Path:导入脚本的路径,该脚本可在导入过程完成后运行代码,以进行自定义处理。更多信息请参阅 使用导入脚本实现自动化

glTF

  • 嵌入图像处理:控制如何处理嵌入 glTF 场景中的纹理。Discard All Textures(忽略所有纹理)不会导入任何纹理,如果你想在 Godot 中手动设置材质,该选项将非常有用。Extract Textures(提取纹理)将纹理提取为外部图像,从而减小文件大小,并提供更多对导入选项的控制。Embed as Basis Universal(嵌入为基础通用)和Embed as Uncompressed(嵌入为未压缩)分别将纹理以带 VRAM 压缩和不带 VRAM 压缩的方式保留在导入的场景中。

FBX

  • 导入器:使用的导入方法。ufbx 将 fbx 文件作为 fbx 文件处理。FBX2glTF 会在导入时将 fbx 文件转换为 glTF ,需要额外设置。不建议使用 FBX2glTF,除非有特定的理由要使用它而不是 ufbx,或者使用不同的文件格式。

  • 允许几何辅助节点:启用或禁用几何辅助节点

  • 嵌入图像处理:控制如何处理嵌入 glTF 场景中的纹理。Discard All Textures(忽略所有纹理)不会导入任何纹理,如果你想在 Godot 中手动设置材质,该选项将非常有用。Extract Textures(提取纹理)将纹理提取为外部图像,从而减小文件大小,并提供更多对导入选项的控制。Embed as Basis Universal(嵌入为基础通用)和Embed as Uncompressed(嵌入为未压缩)分别将纹理以带 VRAM 压缩和不带 VRAM 压缩的方式保留在导入的场景中。

Blender 专用选项

仅对 .blend 文件可见。

节点

  • 可见:All(全部)会导入所有内容,包括不可见的对象。Visible Only(仅可见)仅导入可见的对象。Renderable(可渲染)仅导入在 Blender 中标记为可渲染的对象,无论它们是否实际可见。在 Blender 中,可渲染性通过在大纲视图(Outliner)中点击每个对象旁边的相机图标来切换,而可见性则通过眼睛图标来切换。

  • 仅活动集合:若勾选此项,则仅导入 Blender 中位于活动集合内的节点。

  • 精确光源:若勾选此项,将从 Blender 导入灯光(方向光、全向光和聚光灯)。“精确(punctual)”不应与“位置(positional)”混淆,因此方向光也包含在内。

  • 摄像机:如果选中,则从 Blender 中导入摄像机。

  • 自定义属性:若勾选此项,将从 Blender 导入自定义属性作为 glTF 的扩展数据。随后,可通过使用编辑器插件GLTFDocument.register_gltf_document_extension()读取这些数据,以便在导入时设置节点元数据(以及其他用途)。

  • 修改器:如果设为 No Modifiers,导入时将忽略物体的修改器。如果设为 All Modifiers,则在导入时将修改器应用于物体。

网格

  • 颜色:如果勾选,则从 Blender 导入顶点颜色。

  • UVs:如果勾选,则从 Blender 导入顶点的 UV1 和 UV2。

  • 法线:如果勾选,则从 Blender 导入顶点法线。

  • 导出几何节点实例:若勾选此项,将从 Blender 导入 几何节点 实例。

  • GPU 实例:如果勾选,则会将实例和粒子系统导入为 GLTF 的缓冲区/访问器数据,而不是大量单独的 Mesh3D 对象。这不包括几何节点实例化 。

  • 切线:如果选中,则从 Blender 导入顶点切线。

  • 蒙皮:None跳过从 Blender 导入骨骼蒙皮数据。4 Influences (Compatible)导入蒙皮数据以兼容所有渲染器,但某些骨骼绑定的精度会降低。All Influences:导入包含所有权重影响(Godot 中最多 8 个)的蒙皮数据,精度更高,但可能无法与所有渲染器兼容。

  • 仅导出影响网格变形的骨骼:若勾选此项,仅从 Blender 导入那些对网格产生变形影响的骨骼。

材质

  • 启用解包:若勾选此项,会将原始图像解包到 Godot 文件系统中并直接使用。这允许修改图像导入设置(如 VRAM 压缩)。若未勾选,则允许 Blender 转换原始图像,例如将粗糙度和金属度重新打包为一个粗糙度+金属度纹理。大多数情况下,应保持此选项勾选,但如果 .blend 文件中的图像格式不正确,则必须禁用此选项才能获得正确行为。

  • 导出材质:若设置为 Placeholder:不导入材质,但保留表面插槽,以便为不同表面单独分配材质;若设置为 Export,则按原样导入材质(注意:Blender 的程序化材质可能无法正确工作)。若设置为 Named Placeholder,则导入材质,但不导入打包在 .blend 文件中的图像。纹理需要在导入后的材质中手动重新指定。

动画

  • 限制播放范围:若勾选此项,则将动画导入限制在 Blender 中定义的播放范围(即 Blender 动画时间轴右侧的起始结束选项)。这可以避免包含未使用的动画数据,使导入的场景更小、加载更快。然而,如果在 Blender 中未正确设置播放范围,这也可能导致部分动画数据丢失。

  • 始终采样:若勾选此项,将强制在导入时对动画进行采样,以确保 Blender 与 glTF 之间的动画插值方式一致,但代价是文件体积增大。若未勾选,由于两者在动画插值语义上的差异,你在 Blender 中看到的动画与在 Godot 中导入的场景之间可能存在差异。

  • 分组轨道:若勾选此项,则将动画(活动动作和 NLA 轨道上的动作)作为独立的轨道导入。若未勾选,则所有当前分配的动作将合并为一个 glTF 动画。

使用导入脚本实现自动化

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

在文件系统面板中右键单击并选择新建脚本…,创建一个不附加到任何节点的脚本。在脚本编辑器中,编写以下内容:

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

# This sample changes all node names.
# Called right after the scene is imported and gets the root node.
func _post_import(scene):
    # Change all node names to "modified_[oldnodename]"
    iterate(scene)
    return scene # Remember to return the imported scene

# Recursive function that is called on every node
# (for demonstration purposes; EditorScenePostImport only requires a `_post_import(scene)` function).
func iterate(node):
    if node != null:
        print_rich("Post-import: [b]%s[/b] -> [b]%s[/b]" % [node.name, "modified_" + node.name])
        node.name = "modified_" + node.name
        for child in node.get_children():
            iterate(child)

_post_import(scene: Node) 函数以导入的场景为参数(该参数实际上是场景的根节点)。最终使用的场景必须被返回(即使是完全不同的另一个场景)。

要使用你的脚本,请在导入选项卡的“导入脚本”类别下的“路径”选项中找到该脚本。

使用动画库

你可以选择仅从 glTF 文件导入动画,而不导入任何其他内容。这在某些资产管线中用于将动画与模型分开分发。比如,这允许你给多个角色使用一套动画,而无需为每个角色重复动画数据。

要执行此操作,请在文件系统面板中选择 glTF 文件,然后在导入面板中将导入模式更改为 Animation Library:

在导入面板中将导入类型更改为 Animation Library

在导入面板中将导入类型更改为 Animation Library

单击重新导入,并根据提示重启编辑器。重启后,glTF 文件将作为 AnimationLibrary 导入,而不是 PackedScene 。然后,可以在 AnimationPlayer 节点中引用此动画库。

更改导入模式为 Animation Library 后可见的导入选项,其作用与使用场景导入模式时相同。更多信息请参阅 使用导入面板

过滤脚本

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

过滤脚本针对每个导入的动画执行。语法由两种类型的语句组成:第一种用于选择要过滤的动画,第二种用于过滤匹配动画中的单个轨道。所有名称模式都使用不区分大小写的表达式匹配,并支持 ?* 通配符(底层使用 String.matchn() )。

脚本必须以动画过滤语句开头(由以 @ 开头的行表示)。例如,如果我们想要将过滤应用于所有名称以 "_Loop" 结尾的导入动画:

@+*_Loop

类似地,还可以在同一行中添加更多模式,以逗号分隔。下面是一个修改后的例子,除了包含所有名称以 "Arm_Left" 开头的动画外,同时还排除所有名称以 "Attack" 结尾的动画:

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

在动画选择过滤语句之后, 我们添加轨道过滤模式来指示应保留或丢弃哪些动画轨道。如果未指定轨道过滤器模式, 则匹配动画中的所有轨道都会被丢弃!

需要注意的是,轨道过滤语句是按顺序应用于动画中的每条轨道的,这意味着一行可能包含某个轨道,但后续的规则仍然可以丢弃它。同样,一个被之前规则排除的轨道,可以被过滤脚本后续的规则重新包含进来。

例如:包含动画中所有名字以 "_Loop" 结尾的轨道,但忽略任何以 "Control" 结尾的 "Skeleton" 轨道,除非它们的名字中有 "Arm"

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

在上面的示例中,像 "Skeleton:Leg_Control" 这样的轨道会被丢弃,而像 "Skeleton:Head""Skeleton:Arm_Left_Control" 这样的轨道会被保留。

任何一行不是以 +- 开头的轨道过滤都会被忽略。

场景继承

在许多情况下,可能希望对导入的场景进行手动修改。默认情况下,这是不可能的,因为如果源 3D 资产发生变化,Godot 将重新导入整个场景。

然而,可以使用场景继承来创建本地修改。如果你尝试使用场景 > 打开场景...场景 > 快速打开场景... 来打开已导入的场景,以下对话框将会出现:

在编辑器中打开导入的 3D 场景时的对话框

在编辑器中打开导入的 3D 场景时的对话框

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

  • 无法删除基础场景中的节点,但可以在任何地方添加其他节点。

  • 无法编辑子资源。相反,你需要如上所述将它们保存在外部。

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