1. 项目概述:为什么Blender到Godot的资产导出值得你花时间
如果你和我一样,从Blender建模到Godot引擎开发这条路上走过,那你肯定遇到过这样的场景:在Blender里精心雕琢的模型,导出后放进Godot,要么方向错了,要么材质丢了,要么动画不播放,甚至直接报错。这感觉就像精心准备的食材,下锅时才发现锅是漏的。
“Blender到Godot资产导出”这个标题,背后远不止是一个简单的“文件另存为”操作。它是一套从3D建模软件到游戏引擎的无缝衔接工作流,是决定你项目开发效率和质量的关键环节。一个顺畅的导出流程,能让你把90%的精力聚焦在创意和玩法上,而不是浪费在反复调试导入错误的泥潭里。
这篇文章,我会把我这些年踩过的坑、总结的经验,从模型准备、导出设置、引擎集成到问题排查,掰开揉碎了讲给你听。无论你是独立开发者、技术美术,还是刚接触3D游戏制作的新手,这套流程都能帮你建立起一个可靠、高效的资产管线。我们最终的目标是:在Blender里点下“导出”后,资产能“开箱即用”地出现在Godot场景中,材质、动画、碰撞体一应俱全。
2. 核心思路拆解:理解两个世界的“语言”差异
为什么Blender和Godot之间需要“导出”这个步骤?根本原因在于两者是不同领域的工具,有着各自的数据结构和约定。Blender是一个功能全面的3D内容创作套件,而Godot是一个实时渲染的游戏引擎。导出,本质上是一次数据格式的转换和适配。
2.1 坐标系:第一个拦路虎
这是新手最容易栽跟头的地方。Blender默认使用右手坐标系,Z轴向上。这意味着在Blender的3D视图中,地面是XY平面,高度方向是Z轴。
而Godot,为了与OpenGL等图形API保持一致,使用的是右手坐标系,Y轴向上。在Godot的3D编辑器中,地面是XZ平面,高度方向是Y轴。
这个差异直接导致了最经典的“模型躺倒”问题:你在Blender里站着的人,导入Godot后直接“躺平”了。更复杂的是方向约定:在3D资产领域(尤其是glTF标准),通常约定模型的前方是+Z轴。但在Godot的摄像机视角里,前方是-Z轴。听起来有点绕,但理解这一点至关重要,它影响着角色移动、摄像机跟随、look_at函数等一切与方向相关的逻辑。
实操心得:不要试图在Godot里用旋转去硬修正方向错误。正确的做法是在导出阶段就处理好。对于角色、车辆等有前后概念的资产,确保其在Blender中面朝+Y轴(这样其局部+Z轴就指向了Blender的+Y方向)。对于地形、建筑等无方向性的资产,则使用东南西北(+X东, -X西, +Z南, -Z北)来思考。
2.2 数据结构的映射
Blender中的一个场景文件(.blend)包含网格、材质、纹理、骨骼、动画、摄像机、灯光等复杂数据。Godot的核心组织单元是“场景”(.tscn),由节点树构成。导出过程需要完成以下映射:
- 网格数据-> Godot的
MeshInstance3D节点及其内部的ArrayMesh资源。 - 材质和着色器-> Godot的
StandardMaterial3D或ShaderMaterial。PBR(基于物理的渲染)工作流是当前的主流,你需要确保法线贴图、金属度、粗糙度等纹理通道正确传递。 - 骨骼与动画-> Godot的
Skeleton3D节点和AnimationPlayer资源。这里涉及到骨骼名称、层级关系、动画关键帧数据的转换。 - 变换(位置、旋转、缩放)-> Godot节点的
transform属性。导出前在Blender中“应用变换”(Ctrl+A)是避免缩放问题的最佳实践。
2.3 导出格式选型:为什么glTF是首选
可供选择的格式不少:FBX、OBJ、DAE (Collada)、glTF,甚至直接导入.blend文件。Godot官方文档明确推荐glTF 2.0,这是有充分理由的:
- 开放性标准:glTF是Khronos Group(OpenGL、Vulkan背后的组织)制定的标准,专为实时应用传输3D资产设计,没有专利壁垒。
- 数据完整性:一个
.gltf或.glb文件可以打包网格、材质、纹理、动画、摄像机、灯光甚至场景层级,是真正的“一站式”格式。.glb(二进制格式)更是将一切打包进单个文件,管理起来非常方便。 - 引擎原生支持:Godot对glTF的支持是最深入、最稳定的。很多引擎的高级特性(如PBR材质定义、骨骼动画)都能通过glTF完美导入。
- Blender生态完善:Blender内置的glTF 2.0导出插件(通常通过“Khronos Group”的官方插件或Blender 2.8+的内置功能)非常成熟,提供了大量针对Godot等引擎的优化选项。
相比之下,FBX是Autodesk的私有格式,虽然通用但可能遇到版本兼容性问题;OBJ不支持动画和复杂材质;DAE已逐渐被淘汰;直接导入.blend文件依赖于Godot内部的Blender文件解析器,更新可能不及时,且增加了引擎的复杂度。
结论:对于绝大多数情况,将glTF 2.0(尤其是.glb格式)作为Blender到Godot的首选资产交换格式,是最稳妥、最高效的选择。
3. Blender端模型准备:导出前的“大扫除”
在点击导出按钮之前,在Blender里做好准备工作,能避免90%的后续问题。我把这个过程称为“资产清理”。
3.1 网格拓扑与数据优化
三角化(Triangulate):GPU只能渲染三角形。虽然Godot导入器可以帮你三角化四边形或N边形,但结果可能不可预测,特别是对于复杂的凹多边形或带有洞的面。务必在导出前手动三角化。
- 方法:在编辑模式下,选择所有面,按
Ctrl+T,或者添加“三角化”修改器并应用它。 - 检查:在“视图叠加层”中开启“面朝向”显示,确保所有面都是三角形且法线方向一致(蓝色朝外)。
- 方法:在编辑模式下,选择所有面,按
应用变换(Apply Transforms):这是黄金法则。Blender中对象的缩放、旋转值如果不是1和0,会导致导入Godot后缩放异常、碰撞体错位等问题。
- 操作:选中所有要导出的对象,按
Ctrl+A,选择“全部变换”。观察物体的缩放(Scale)是否变为(1,1,1),旋转(Rotation)是否变为(0,0,0)。位置(Location)可以不用归零,但需注意其代表的是原点偏移。
- 操作:选中所有要导出的对象,按
检查并清理顶点组(Vertex Groups):顶点组主要用于蒙皮权重。确保只有需要蒙皮的网格有顶点组,并且组名与骨骼名称对应。删除那些无用的、测试留下的顶点组,可以减少文件大小和潜在错误。
检查UV映射:确保所有模型都有正确的UV展开,并且没有重叠或拉伸严重的UV岛。对于需要光照贴图的静态物体,可能需要准备第二套UV(UV2)。
3.2 材质与纹理准备
Godot的3D材质系统基于PBR(金属度/粗糙度工作流)。你需要准备一套标准的PBR纹理贴图:
- 反照率(Albedo):基础颜色贴图,不应包含光照信息。通常为sRGB颜色空间。
- 法线(Normal):切线空间法线贴图。在Blender中制作法线贴图时,注意导出设置。Godot期望的是OpenGL风格的法线(Y+向上),而有些工具或DirectX风格是Y-向上。如果法线看起来不对,可以在Godot的导入设置中勾选“法线贴图翻转Y”。
- 金属度(Metallic):单通道灰度图,白色表示完全金属,黑色表示非金属。
- 粗糙度(Roughness):单通道灰度图,白色表示非常粗糙,黑色表示非常光滑。
- 环境光遮蔽(Ambient Occlusion, AO):单通道灰度图。有时会与金属度/粗糙度打包进同一张图的G和B通道(即ORM或ORM贴图)。
注意事项:在Blender中,如果你使用“原理化BSDF”着色器,其“粗糙度”参数可以直接对应Godot的粗糙度。但“金属度”参数需要确保是0或1,或者对应一张贴图。将纹理图像节点正确连接到着色器后,在导出时,glTF导出器通常会尝试将这些连接关系转换为glTF的PBR材质定义。
3.3 骨骼、绑定与动画准备
- 骨骼朝向与命名:确保骨骼的朝向正确(通常骨骼的局部Y轴指向下一个骨骼)。给骨骼起一个清晰、唯一的名称,避免使用中文或特殊字符。这有助于在Godot中识别和编写脚本。
- 重置姿态:在导出动画或静态模型前,确保骨架处于T-Pose或Rest Pose(放松姿势)。在姿态模式下,选中所有骨骼,按
Alt+R(重置旋转),Alt+G(重置位置),Alt+S(重置缩放)。然后回到物体模式。 - 动作(Actions):每个独立的动画(如Idle, Run, Jump)在Blender中应保存为单独的Action。在导出glTF时,你可以选择导出当前场景中所有的NLA动作。
- 权重绘制:确保蒙皮权重平滑,没有过度的拉扯或关节处不自然的变形。可以使用“权重绘制”模式下的模糊、平滑工具进行优化。
3.4 场景组织与层级
- 空对象(Empties):在Blender中,你可能会用空对象作为组、控制器或挂点。glTF导出器可以将空对象导出为Godot中的
Node3D节点。这非常有用,例如,你可以在角色的右手位置放一个空对象,导出后,在Godot中这个空对象节点就可以作为武器或道具的挂载点。 - 层级关系:理清对象的父子关系。父对象的变换会影响所有子对象。确保这个层级关系是你希望在Godot中看到的。
4. Blender glTF导出器详解:关键设置逐项解读
打开Blender,选择文件 -> 导出 -> glTF 2.0 (.glb/.gltf)。我们会聚焦于那些对Godot导入至关重要的选项。
4.1 格式(Format)
- glTF 分离(.gltf + .bin + 纹理):生成一个
.gltf(JSON文本)、一个.bin(二进制数据)和一堆外部纹理图片。优点:便于调试,可以单独修改纹理或查看JSON结构。缺点:文件分散,管理稍麻烦。 - glTF 嵌入(.gltf):所有数据(包括纹理)都以Base64编码嵌入到单个
.gltf文本文件中。文件巨大,不推荐。 - glTF 二进制(.glb):强烈推荐。所有数据打包进一个
.glb二进制文件。干净、便携、易于版本管理。
4.2 包含(Include)
- 选中的物体:如果你只想导出场景中的特定模型,就勾选这个。
- 可见物体:只导出当前可见的物体。在复杂场景中分层导出时有用。
- 场景:导出整个场景。通常勾选此项。
- 自定义属性:Blender物体的自定义属性(Custom Properties)可以被导出,并作为Godot中节点的元数据(meta)导入。这是一个非常强大的功能,可以用于传递游戏逻辑相关的参数(如敌人类型、血量等)。
4.3 变换(Transform)
- Y向上:必须勾选。这是将Blender的Z-up坐标系转换为Godot(及glTF标准)Y-up坐标系的关键。勾选后,导出的模型在Godot中就是直立状态。
- 应用变换:如果你已经在Blender中应用了所有变换(Ctrl+A),这里可以不勾选。但勾选上是一个双保险,导出器会帮你再应用一次。
4.4 几何数据(Geometry)
- 应用修改器:务必勾选。这确保了你在Blender中添加的细分表面、阵列、三角化等修改器效果被实际计算到导出的网格中。
- UV:导出主UV(UVMap)和次UV(UVMap.001等)。确保勾选。
- 法线:导出顶点法线。必须勾选。
- 切线:对于使用法线贴图至关重要。必须勾选。如果网格没有切线,导出器会尝试生成。
- 顶点颜色:如果你的模型使用了顶点色,勾选此项。
- 材质:必须勾选。导出材质设置。
- 压缩:启用网格数据压缩,可以减小文件大小。对Godot兼容性好,建议开启。
4.5 动画(Animation)
- 动画:勾选以导出动作。
- 范围:选择“当前帧”或指定一个帧范围来导出特定动画。
- 采样率:定义每秒采样多少关键帧。Blender动画通常是24或30 FPS。Godot的AnimationPlayer可以处理任意采样率,但保持一致性更好。通常保持默认(与场景帧率相同)即可。对于简单的循环动画,适当降低采样率可以减小文件。
- 总是采样动画:强制在每一帧采样,即使该帧没有关键帧。这能保证动画曲线平滑,但文件会变大。对于线性或步进式动画,可以不勾选。
- 变形动画(Shape Keys):如果你使用了形态键(Blender)或混合形状(glTF)来做面部动画等,勾选此项。
- 骨骼(Skinning):导出骨骼和蒙皮信息。必须勾选,如果你导出的模型是绑定的。
4.6 高级设置(Advanced)
- 摄像机/灯光:通常,我们在Godot中重新布置灯光和摄像机,所以可以不导出。但如果你想保留Blender中的布局作为参考,可以勾选。
- 批量导出:如果你有多个.blend文件或集合需要导出,可以使用这个功能。
一个典型的、安全的导出预设配置如下表所示:
| 选项分类 | 关键选项 | 推荐设置 | 原因说明 |
|---|---|---|---|
| 格式 | 文件格式 | glTF 二进制 (.glb) | 单文件,易管理,Godot支持好。 |
| 包含 | 导出范围 | 场景(或 选中的物体) | 根据需求选择整个场景或部分资产。 |
| 变换 | Y向上 | 勾选 | 适配Godot的Y-up坐标系,解决模型“躺倒”问题。 |
| 应用变换 | 勾选(或确保已在Blender中应用) | 避免导入Godot后出现非均匀缩放等变换问题。 | |
| 几何数据 | 应用修改器 | 勾选 | 确保细分、三角化等修改器效果被烘焙进网格。 |
| UVs, 法线, 切线 | 全部勾选 | 确保材质和法线贴图正常工作。 | |
| 材质 | 勾选 | 导出材质信息。 | |
| 压缩 | 勾选 | 减小文件体积。 | |
| 动画 | 动画 | 按需勾选 | 导出动作数据。 |
| 采样率 | 保持默认(如24) | 与Blender场景帧率一致。 | |
| 骨骼 | 勾选(如为角色) | 导出蒙皮信息。 |
设置好后,可以点击“导出”按钮右侧的“+”号保存这个预设,以后导出同类资产时一键调用,非常方便。
5. Godot端导入与集成:让资产“活”起来
将.glb文件拖入Godot的“文件系统”面板,导入过程会自动开始。但“导入”不等于“可用”,我们还需要进行一些配置和场景组装。
5.1 理解导入过程与.import文件
当你把外部资产(如.glb,.png,.wav)拖入Godot项目时,Godot并不会直接使用原文件。它会根据资产类型,在后台创建一个同名的.import文件(如character.glb.import),并将原文件处理成引擎内部优化的格式(通常放在.godot/imported/目录下)。
.import文件是一个文本文件,它记录了针对该资产的所有导入设置。双击资产,或在导入面板中调整设置后,Godot会根据新的设置重新处理原文件。理解这一点很重要:修改导入设置后,需要重新导入才能生效。
5.2 3D场景的导入设置
选中导入的.glb文件,在“导入”停靠面板中,你会看到丰富的选项:
常规(General):
- 根类型(Root Type):默认是
Node3D。如果你的glTF文件包含一个完整的场景(多个物体、灯光、摄像机),保持默认即可。如果只是一个单一网格(如一个道具),也可以选择MeshInstance3D。 - 创建碰撞体(Create Collision):强烈建议勾选。Godot可以自动为你的网格生成简化版的碰撞体(凸包或三角网格)。对于静态环境物体,选择“简化碰撞体(Convex)”通常性能更好;对于需要精确碰撞的复杂静态网格,可以选择“三角网格碰撞体(Trimesh)”。
- 创建导航网格(Create Navigation):如果你希望这个模型参与AI导航,可以勾选,Godot会为其生成一个导航网格。对于复杂地形,通常更推荐在Godot中使用
NavigationRegion3D节点单独烘焙。 - 创建遮挡器(Create Occluder):用于遮挡剔除,优化性能。对于大型、简单的遮挡物(如墙壁)可以考虑。
- 根类型(Root Type):默认是
网格(Meshes):
- 压缩(Compression):启用顶点数据压缩,节省内存。对视觉质量影响极小,建议开启。
- 确保切线(Ensure Tangents):如果导出时已包含切线,则无需勾选。如果法线贴图出现问题,可以尝试勾选此选项让Godot重新计算切线。
动画(Animations):
- 导入动画(Import Animations):默认勾选。如果glTF文件中包含动画,这里会列出所有动作。
- 循环(Loop):为每个动画设置是否循环。对于Idle、Run这类动画,勾选它。
- 重定向(Retarget):高级功能。如果你有多个骨架结构相似的角色(如人形),你可以将其中一个角色的动画重定向到另一个角色上。这需要设置“骨骼映射(Bone Map)”。
高级(Advanced):
- 存储(Storage):默认“文件系统(Filesystem)”即可。如果选择“嵌入(Embedded)”,网格数据会直接嵌入到场景中,不利于复用。
- 节点(Nodes):可以设置导入后节点的命名规则,或通过后缀自动将特定节点转换为特定类型(如
-col后缀的节点自动变成StaticBody3D用于碰撞)。
配置完成后,点击右下角的“重新导入(Reimport)”。Godot会重新处理文件,并在文件系统面板中,该资源的类型图标会从“外部资源”变成“内部资源”(如PackedScene)。
5.3 从导入资源到场景实例
现在,你可以像使用任何其他Godot场景一样使用这个导入的资源:
- 直接拖入场景:将
.glb文件从文件系统面板拖到3D视口或场景树中。Godot会将其作为一个PackedScene实例化。 - 在代码中加载:
var character_scene = load("res://assets/characters/hero.glb") var character_instance = character_scene.instantiate() add_child(character_instance) - 检查与调整:实例化后,在场景树中展开节点。你应该能看到一个清晰的层级结构,通常包含:
- 一个根节点(如
Node3D)。 - 一个或多个
MeshInstance3D节点。 - 一个
Skeleton3D节点(如果模型有骨骼)。 - 一个
AnimationPlayer节点(如果模型有动画)。 - 自动生成的
CollisionShape3D节点(如果启用了创建碰撞体)。
- 一个根节点(如
此时,你的模型应该已经正确显示在Godot视口中,材质基本正确,碰撞体也已就位。
5.4 材质与纹理的微调
尽管glTF/PBR流程已经很标准化,但有时导入的材质在Godot中看起来还是会有些差异(特别是金属度/粗糙度的感觉)。你可以在MeshInstance3D的“材质覆盖”属性中,找到导入的StandardMaterial3D进行微调:
- 调整粗糙度/金属度:如果模型看起来太“塑料”或太“金属”,可以微调这两个参数。
- 检查纹理:在材质的相应槽位中,检查纹理是否被正确加载。特别是法线贴图,如果效果相反,勾选材质中法线贴图的“翻转Y”选项。
- 透明度:如果模型有透明部分(如树叶),确保材质的“透明度”模式设置为“Alpha Blend”或“Alpha Scissor”,并调整“Alpha Scissor Threshold”。
实操心得:不要直接在导入的
.tres材质资源上修改。因为一旦重新导入glTF文件,这个材质资源可能会被覆盖。更好的做法是:在MeshInstance3D的“材质覆盖”属性中,复制这个材质(点击下拉框选择“快速加载”,然后右键选择“复制”),然后在副本上进行修改。这样,原始导入的材质保持不变,你的修改也不会被覆盖。
5.5 动画系统的对接
如果导入了动画,场景中会有一个AnimationPlayer节点。打开动画面板,你应该能看到所有导入的动作。
- 检查动画:播放一下,看看动作是否流畅,有没有奇怪的变形。
- 设置循环:在动画面板中,选中一个动画,在“循环”选项打勾。
- 动画重定向(高级):如果你有多个角色共享一套动画,可以使用Godot的“骨架重定向”功能。这需要你创建一个
SkeletonProfile(如SkeletonProfileHumanoid),并建立两个骨架之间的骨骼名称映射关系。然后在AnimationPlayer的“重定向”设置中指定源骨架和目标骨架的Profile。
6. 常见问题与排查技巧实录
即使流程再规范,问题也难免会出现。下面是我遇到过的典型问题及其解决方案。
6.1 模型方向/旋转错误
- 症状:模型在Godot中躺倒、倒立或朝向错误。
- 排查:
- 首先检查Blender导出设置中的“Y向上”是否勾选。
- 在Blender中,检查模型的初始朝向。对于角色,确保其面朝+Y轴(在Blender的顶视图看,脸朝向上方)。
- 在Godot中,检查导入的根节点的旋转值。如果问题轻微,可以尝试在根节点上施加一个旋转修正(例如,绕X轴旋转-90度)。但这只是临时补救,根源应在Blender中修正。
6.2 材质丢失或显示为粉色
- 症状:模型显示为Godot的缺失材质颜色(默认是粉色)。
- 排查:
- 检查glTF文件是否嵌入了纹理,或者纹理图片是否在正确路径。对于分离格式(.gltf + .bin + 图片),确保所有图片文件与.gltf文件在同一目录或相对路径正确。
- 在Godot的导入面板中,查看该资源的“依赖”列表,看是否有纹理文件丢失。
- 检查材质资源是否被正确创建。双击
MeshInstance3D的材质,查看其纹理槽位是否为空。 - 常见原因:Blender中使用的纹理路径是绝对路径,或者纹理节点连接方式不被glTF导出器支持。尝试在Blender中将所有纹理图片打包到.blend文件中(图像编辑器里,图片 -> 打包),或者使用相对路径。
6.3 法线贴图看起来不对
- 症状:光照下凹凸感是反的,或者看起来扁平。
- 排查:
- 在Godot的材质中,找到法线贴图设置,尝试勾选或取消勾选“翻转Y”。
- 在Blender中,确保法线贴图是“切线空间(Tangent Space)”法线,而不是“物体空间”或“世界空间”。
- 检查Blender的glTF导出设置中,“法线”和“切线”选项是否都已勾选。
6.4 动画不播放或变形怪异
- 症状:
AnimationPlayer里有动画,但播放时模型不动,或者骨骼扭曲。 - 排查:
- 确保在导出前,Blender中的骨架已重置到T-Pose/放松姿势。
- 检查Godot中的
Skeleton3D节点,点击“显示骨骼”,查看骨骼层级和位置是否正确。 - 播放动画时,观察
Skeleton3D节点的“姿势”属性是否在变化。如果不变,可能是动画数据没有正确绑定到骨架上。 - 对于变形怪异,通常是蒙皮权重问题。回到Blender,检查问题区域的权重绘制,确保权重平滑且主要受1-2根骨骼影响,避免多根骨骼权重均等。
6.5 碰撞体形状不正确或缺失
- 症状:物体穿模,或者
CollisionShape3D的形状与视觉模型严重不符。 - 排查:
- 确认在Godot导入设置中勾选了“创建碰撞体”,并选择了合适的类型(凸包或三角网格)。
- 凸包碰撞体是性能最优选,但它会包裹模型的整个凸形外壳。对于凹形物体(如碗、房间),凸包碰撞体会填满内部空间,导致角色无法进入。此时应使用“三角网格碰撞体”,但请注意,三角网格碰撞体只能用于
StaticBody3D,不能用于RigidBody3D或CharacterBody3D。 - 对于需要复杂碰撞的动力学物体,更好的做法是:在Blender中创建一个简化的、仅用于碰撞的低模网格,将其命名为
模型名-collision,并作为原模型的子级。在导出设置中,Godot的glTF导入器可以识别-col后缀并自动为其生成碰撞体节点。
6.6 性能问题:面数过多或Draw Call过高
- 症状:场景帧率低下,编辑器提示Draw Call过多。
- 排查:
- 在Blender中检查模型的面数。对于远处或小物体,面数应尽可能少。
- 使用Godot的LOD(细节层次)功能。为高模创建一个低模版本,在Godot中使用
LOD节点或通过脚本根据距离切换模型。 - 合并材质。确保一个模型不要使用过多不同的材质球。在Blender中,尽量将使用相同材质、相同纹理的网格合并。
- 使用
MultiMeshInstance3D来实例化大量相同的物体(如草地、树木),这能极大降低Draw Call。
问题速查表:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 模型躺倒/旋转错 | 坐标系未转换 | Blender导出时勾选“Y向上”;检查模型初始朝向。 |
| 材质粉色丢失 | 纹理路径错误/未导出 | 在Blender中打包纹理;检查Godot导入依赖。 |
| 法线凹凸错误 | 切线空间或Y方向错误 | 在Godot材质中切换“法线贴图翻转Y”。 |
| 动画不播放 | 骨架未重置/动画未绑定 | 导出前Blender中骨架重置为T-Pose;检查Godot中Skeleton3D节点。 |
| 碰撞体形状怪 | 碰撞类型选择不当 | 凹物体用三角网格;动态物体需用凸包或简单形状组合。 |
| 导入后文件很大 | 未压缩/包含多余数据 | 导出时开启压缩;Blender中删除多余顶点组、形状键。 |
| 重新导入后修改丢失 | 直接修改了导入生成的资源 | 对材质等进行“复制”后再修改,避免覆盖。 |
7. 进阶工作流与自动化
当你需要处理大量资产时,手动一个个导出和导入是低效的。这里有一些提升效率的思路。
7.1 使用Blender的Python脚本进行批量导出
你可以编写一个Blender Python脚本,遍历场景中的特定集合或对象,应用统一的清理操作(应用变换、三角化),然后以预设好的glTF设置进行批量导出。
# 示例:一个简单的Blender脚本框架,用于批量导出选中的物体为glb import bpy import os # 设置导出路径 export_path = "/path/to/your/godot/project/assets/" # 遍历选中的物体 for obj in bpy.context.selected_objects: if obj.type == 'MESH': # 确保物体是激活状态 bpy.context.view_layer.objects.active = obj obj.select_set(True) # 这里可以添加预处理步骤,如应用变换、三角化 # bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) # bpy.ops.object.modifier_add(type='TRIANGULATE') # bpy.ops.object.modifier_apply(modifier="Triangulate") # 设置导出文件名 file_name = obj.name + ".glb" full_path = os.path.join(export_path, file_name) # 调用glTF导出操作符(需要先设置好上下文) # 注意:这需要你预先在UI中配置好glTF导出预设并获取其名称 # 更可靠的方式是直接设置bpy.ops.export_scene.gltf的参数 bpy.ops.export_scene.gltf( filepath=full_path, use_selection=True, export_format='GLB', export_yup=True, # 关键! export_apply=True, export_materials='EXPORT', export_animations=False, # 根据需求调整 export_skins=False, # 根据需求调整 ) print(f"Exported: {file_name}") obj.select_set(False) print("Batch export finished.")7.2 利用Godot的导入后脚本(Post-Import Script)
Godot支持为导入的资源附加一个“后处理”脚本。在导入面板的“高级”部分,你可以指定一个GDScript脚本。这个脚本会在资源导入后自动运行,允许你以编程方式修改生成的场景。
例如,你可以用脚本自动为所有导入的静态网格添加到一个特定的碰撞层(Collision Layer),或者为所有角色模型添加一个特定的脚本。
# post_import.gd extends EditorScenePostImport func _post_import(scene): # scene 是刚刚导入的 PackedScene 资源 var instance = scene.instantiate() # 遍历所有 MeshInstance3D 节点 _process_node(instance) # 返回修改后的场景 return scene func _process_node(node): if node is MeshInstance3D: # 示例:自动添加一个 OmniLight3D 作为子节点(用于调试) # var light = OmniLight3D.new() # light.light_color = Color(1, 0, 0) # light.omni_range = 5 # node.add_child(light) # light.owner = node # 重要:设置owner以便保存到场景 # 示例:设置碰撞层为第2层 if node.has_node("CollisionShape3D"): var collision_parent = node.get_node("CollisionShape3D").get_parent() if collision_parent is StaticBody3D or collision_parent is Area3D: collision_parent.collision_layer = 2 # 递归处理子节点 for child in node.get_children(): _process_node(child)7.3 版本控制与团队协作
对于团队项目,资产管线的一致性至关重要。
- 忽略文件:在版本控制系统(如Git)的
.gitignore中,添加*.import和.godot/imported/。这些是生成的中间文件,不应该纳入版本管理。只提交原始的.blend,.glb,.png等源文件。 - 共享导入设置:Godot的导入设置是基于每个项目的。为了确保团队成员导入效果一致,可以考虑将关键的导入设置(如3D模型的碰撞体生成选项)通过项目设置进行一定程度的统一,或者建立团队文档来规范导出/导入流程。
- 使用Godot的“资源管道”:对于需要复杂处理的资产(如自动生成LOD、合并纹理图集),可以研究编写Godot的
EditorImportPlugin来创建自定义的导入器,但这属于更高级的主题。
从Blender到Godot的资产导出,远不止是一个技术步骤,它是连接艺术创作与程序逻辑的桥梁。一个稳定、高效的管线,能让你和你的团队更专注于游戏本身的核心乐趣。希望这篇指南能帮你扫清路上的障碍。如果在实践中遇到这里没覆盖的古怪问题,我的经验是:回归基础,检查坐标系、检查变换、检查数据完整性——大多数问题都藏在这些最基本的环节里。