mcpField
S
scenario-blender-export

scenario-blender-export

github.com/scenario-labs创意与媒体1.2k117 次安装1 天前更新
代码仓库

关于 scenario-blender-export

scenario-blender-export 是用于将 Blender 资产交付到游戏引擎、Web 格式、USD 流程或 3D 打印的技能。它结合各目标的导出预设、交付审核和重新导入比对,检查仅凭导出成功无法发现的差异。

主要功能

  1. 01使用面向引擎的预设导出
  2. 02导出前审核资产
  3. 03重新导入并比对导出文件
  4. 04汇总 GLB 内容和扩展
  5. 05生成 LOD 与碰撞网格
  6. 06批量转换支持的模型格式

适用场景

  1. 01为 Unity 或 Unreal Engine 准备角色 FBX
  2. 02为 Godot 或 Web 导出 GLB
  3. 03通过往返比对检查模型差异
  4. 04转换模型文件夹并查看报告

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/scenario-labs/skills --skill scenario-blender-export

安装后在 Claude Code 中输入/scenario-blender-export确认已加载。

附带文件references/engines.mdscripts/bx_export.py

详细介绍

Blender 导出(引擎就绪文件)

只有在文件重新导入并完成测量后,导出才算完成,而不是导出器返回 FINISHED 时。先检查资产是否通过门槛,再使用预设导出,随后往返验证文件。此技能 基于 scenario-blender-expert(执行通道、交付门槛),并会导入其中的脚本,因此请将 这两个技能安装在同一目录下。如果此处提及的同级技能不在可用技能中,请让用户安装 (npx skills add scenario-labs/skills --skill <name>);如需无人值守运行,则根据工具架构继续操作并标明缺口。

工具包:scripts/bx_export.py。各引擎的相关事实及其来源: references/engines.md。

快速参考

目标预设文件引擎端
Unity,静态网格unityFBX导入默认设置
Unity,角色unity_skeletalFBX保持 Bake Axis Conversion 关闭
Unreal EngineunrealFBXConvert Scene Unit(转换为厘米)
Unreal Engine,角色unreal_skeletalFBX一个根骨骼
Godot 4godotGLB导入默认设置;在停靠面板中生成 LOD
RobloxrobloxFBX每个网格 20,000 个三角形
three.js 和 WebwebGLB、meshopt、WebPMeshoptDecoder;不适用于 Godot
任意 glTF 读取器gltfGLB
USD 管线usdUSDC
Apple AR Quick LookusdzUSDZ、2048 纹理
3D 打印print毫米制 STL切片软件按毫米读取

Unity 和 Godot 预设已导入 Unity 6000.3 和 Godot 4.7.2 并完成测量;unreal、 unreal_skeletal 和 roblox 则依据 Epic 和 Roblox 的文档设置,且仅通过 Blender 往返验证。 测量结果见 references/engines.md。

流程

  1. 检查门槛。 运行 scenario-blender-expert 中的 bx_audit.deliverable(parts, profile),并修复所有 错误。留在对象上的缩放会作为节点变换传入引擎。
  2. 选择预设,参见表格。传入文件所需的每个对象:蒙皮网格及其 骨架、LOD 网格及其组,以及渲染网格旁的碰撞网格。
  3. 导出: bxe.export(path, preset, objects, **overrides)。任何导出器关键字参数都会覆盖 预设,例如在 roblox 上设置 bake_anim=True,以导出动画文件。结果会记录所用 设置。
  4. 往返验证: bxe.round_trip(path, objects, preset=...) 会在后台 Blender 中重新导入文件, 不会影响已打开的场景。它会按名称比较尺寸(1 mm)、三角形数量、变形骨骼、根 骨骼(预期为一个)、骨架缩放、形态键以及对象存储的每个动作。随后列出所有差异。 请逐项修复,或说明其为何符合预期。
  5. glTF 内容: bxe.glb_summary(path) 无需 Blender 即可列出 extensions_required、形态目标、蒙皮、 动画片段和图像类型。若文件需要的扩展不受支持,加载器会拒绝该文件。
  6. 引擎检查: 将文件导入引擎并检查,可使用 scenario-unity-pipeline-automation、 scenario-unreal-pipeline-automation 或 scenario-godot-pipeline-automation。

缩放、轴向和单位

  • Blender 使用米制单位,Z 轴朝上,资产正面朝向 -Y。glTF 使用米制单位,Y 轴朝上(export_yup)。FBX 将轴向存储为元数据;预设会将 -Z 设为前向、Y 设为上向。
  • 将 scene.unit_settings.scale_length 保持为 1.0。其他任何值都会缩放每次导出。
  • 导出前应用对象缩放:obj.data.transform(Matrix.Diagonal(obj.scale).to_4x4()),然后设置 obj.scale = (1, 1, 1),这样引擎节点导入时的缩放为 1。
  • FBX 缩放:unity 写入 FBX_SCALE_ALL(Unity 读取的文件缩放为 1)。unreal 保留 FBX_SCALE_NONE(Unity 读取的文件缩放为 0.01,即以厘米为单位的文件)。roblox 使用 FBX_SCALE_UNITS,符合 Roblox 的导出要求。
  • STL 不包含单位信息,切片软件会按毫米读取,因此 print 会乘以 1000。

角色

  • 将骨架与网格一同导出。use_armature_deform_only 会排除控制骨,因此所有变形骨都必须位于同一根骨骼之下的单个层级中。Unreal 的导入器会报告“Found multiple roots. The importer only supports one root per mesh.”(发现多个根骨。导入器仅支持每个网格有一个根骨。)
  • 所有预设都关闭了 add_leaf_bones。如果保持开启,每条骨骼链都会多出一根末端骨骼,从而破坏重定向。
  • unity_skeletal 和 unreal_skeletal 会烘焙每个动作(bake_anim_use_all_actions),每个动作对应一个动画片段。Unity 会将每个片段命名为 Armature|Action(实测:Rig|Wave),因此动作名称应与片段显示名称一致。glTF 会将每个动作作为一个以其自身名称命名的动画导出。
  • roblox 不导出动画。若要导出动画文件,请将 bake_anim=True 传给 export() 和 round_trip(),后者也会比较动作。
  • 形状键会通过 FBX(混合形状)、glTF(变形目标,名称位于 extras.targetNames)和 USD 传递。构建 ARKit 或 viseme 集合属于 scenario-blender-rigging 的工作。
  • Roblox:每个顶点最多有 4 个影响,骨骼必须冻结(缩放为 1、旋转为 0),根骨位于原点且不受任何影响,每个网格只有一个动画轨道。使用 max(len(v.groups) for v in obj.data.vertices) 检查影响数。

LOD 和碰撞

  • bxe.lods(obj, ratios=(0.5, 0.25)) 会将网格重命名为 Name_LOD0,并在名为 Name 的空对象下添加经过减面处理的 Name_LOD1..n;该空对象会取代网格,位于其父级之下。仅适用于静态网格:带蒙皮的网格会被拒绝。Unity 会根据这些名称构建 LOD Group。Godot 会在导入时生成 LOD(Generate LODs)。Unreal 的文档说明为“Import LODs”,且所有 LOD 共用一个枢轴点。该组会作为普通 FBX Null 导出,Unreal 对其的导入情况尚未测量。
  • bxe.collision(obj, engine, shape) 会添加一个以导入器要求命名的碰撞网格:
    • Unreal:UCX_Name_00(凸包)或 UBX_Name_00(方盒),与模型一起导出到同一个 FBX。
    • Godot:convex(单个凸包)和 box(边界框,即方盒碰撞体)使用 Name-convcolonly;mesh(将网格作为三角网格,仅适用于静态物体)使用 Name-colonly。
    • Unity 和 Roblox:返回 None。碰撞体需在编辑器中设置。
  • 减面可能会破坏 UV 接缝和轮廓。导出前使用 bx_review 检查每个 LOD。

批量转换

blender -b --factory-startup --python-exit-code 1 -P bx_export.py -- \
        --batch /abs/in /abs/out --preset godot --profile game

对文件夹中的每个模型(GLB、glTF、FBX、OBJ、USD、STL、PLY):导入到空场景中,运行交付检查门,使用预设导出,重新导入并比较。它会将每个文件的检查门错误、大小和往返差异写入 /abs/out/report.json。单个文件失败不会中止整个文件夹:该文件会得到一个 failed 条目。两个输入文件同名时,输出名称会保留其格式(hero_fbx.glb、hero_glb.glb)。宣布批处理完成前,请先打开报告。

示例:将生成的 GLB 用于 Unity 和 Godot

import sys
sys.path.append("/abs/skills/scenario-blender-expert/scripts")
sys.path.append("/abs/skills/scenario-blender-export/scripts")
import bpy, bx_audit, bx_export as bxe

bpy.ops.wm.read_factory_settings(use_empty=True)
bpy.ops.import_scene.gltf(filepath="/abs/in/robot.glb")
parts = [o.name for o in bpy.context.scene.objects if o.type == "MESH"]
gate = bx_audit.deliverable(parts, profile="game")
print(gate["errors"])            # fix each one, then gate again until "pass" is True

bxe.export("/abs/out/robot.fbx", "unity", parts)
print(bxe.round_trip("/abs/out/robot.fbx", parts, preset="unity")["diffs"])   # []
bxe.export("/abs/out/robot.glb", "godot", parts)
print(bxe.glb_summary("/abs/out/robot.glb")["extensions_required"])            # []

生成的 GLB 通常会为每个部件包含一个对象,且所有对象共用资产的枢轴点。如果引擎需要为部件制作动画或替换部件,请保留为独立对象。若要制作单个静态道具,请将它们合并(选中这些部件后运行 bpy.ops.object.join),然后再次运行检查门。

常见错误

  • 在 FINISHED 时调用导出。导出器会成功处理引擎以 100 倍比例导入的文件,或未带皮肤的文件。
  • 导出蒙皮网格时未包含其骨架,或导出骨架时未包含其网格。
  • 设置 Bake Axis Conversion 或 Apply Transform 来移除骨架节点的旋转:两者都无法移除旋转,而且前者会让角色转向。
  • 为 Godot 使用 web 预设,或为没有相应解码器的加载器使用压缩 GLB。请先检查 extensions_required。
  • FBX 纹理仍为外部路径:预设会复制并嵌入纹理(path_mode="COPY"、embed_textures=True),因此文件可独立使用。对于 export() 而言,没有扩展名的打包图像(如 GLB 导入后留下的图像)会先获得 .jpg 或 .png 文件名。尚未保存的图像(新建的烘焙目标)或修改过的图像会以像素打包副本的形式随文件一起导出(packed_unsaved_images)。
  • 带纹理的 FBX 在 Unity 中显示为无纹理:默认导入会将嵌入的纹理保留在文件内。在 Materials 选项卡中使用 Extract Textures 将纹理提取到模型文件夹后,即可为其指定纹理。
  • 使用 Blender 比例的 STL:一个 10 cm 的零件打印出来只有 0.1 mm。
  • 导出的 LOD 未经检查:简化可能会导致细薄部件塌陷。

评论

支持 Markdown