关于 scenario-godot-3d-world
scenario-godot-3d-world 是面向构建和审查 Godot 4.7.2 3D 关卡与环境的 Agent 技能。工具包涵盖玩家移动、白盒关卡、地形、资源导入、散布和流式加载,并提供代码检查与画面捕获。
主要功能
- 013D 玩家控制器与楼梯测试
- 02CSG 白盒关卡和布局验证
- 03地形与 GridMap 构建
- 04GLB 导入和道具审计
- 05场景散布与单元流式加载
- 06关卡审计和性能分析
适用场景
- 01测试玩家在楼梯和斜坡上的移动
- 02构建并检查关卡白盒
- 03处理地形和导入道具
- 04分析流式或已布置场景的性能
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-godot-3d-world安装后在 Claude Code 中输入/scenario-godot-3d-world确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/gd_world.pyscripts/agentkit/world/post_import_prop.gdworld_audit.gdworld_blockout.gdworld_common.gdworld_import.gdworld_kit.gdworld_mesh.gdworld_player.gdworld_project.gdworld_scatter.gdworld_stream.gdworld_terrain.gdworld_terrain3d.gdscripts/agentkit/world/runtime/cell_streamer.gdthird_person_controller.gd详细介绍
Godot 3D 世界(关卡与环境美术师)
目标:Godot 4.7.2.stable、macOS Apple Silicon、Jolt Physics、Forward+。
必备背景知识: scenario-godot-expert(channels、gd_run、review loop、4.7 陷阱)。如果你的可用技能中缺少此处提到的同级技能,请让用户安装它(npx skills add scenario-labs/skills --skill <name>);若无法等待用户回复,则根据工具架构继续操作,并标明这一缺口。
状态(2026-10-02): tests/code/godot-3d-world/test_world_live.py 中的全部 14 组在线测试均已通过(live_20261002-215949.json);L8 和 L12 已扩展,并在第 2 轮再次通过(live_20261002-223935.json)。11 项离线检查均已通过。详情请参阅 references/procedures.md。
工具包:scripts/gd_world.py(运行器端)和 scripts/agentkit/world/*.gd(任务、一个导入后脚本和两个运行时脚本),通过 gd_world.install_world(P) 安装。
立场(专家经验总结)
- 先将 Y 设为 0,再归一化相机相对方向。 GDQuest(JlgZtOFMdfc 00:22:00): 否则,向下看会让行走变慢。采用正确顺序后,控制器在俯仰角为 -60 度时仍能保持 6.00 m/s。
- CharacterBody3D 需要楼梯模块,台阶高度必须根据踏面确定。 Majikayo
(Tb-R3l0SQdc 00:17:01)使用
body_test_motion向上贴合,并通过射线检测踏面,因为胶囊体会碰到前缘。半径为 0.35 的标准胶囊体会被 0.18 m 高的台阶挡住。根据胶囊体的移动距离计算高度,会让它爬上 0.6 m 高的台阶,超过 0.45 m 的限制;踏面射线解决了这个问题。 - 使用下方地面的射线检测来保护向下贴合。 Majikayo(00:14:58):没有它,走下任何边缘时都会向下贴合。这个保护措施无法解决过陡的楼梯:要平稳下行,台阶高度应保持在约 0.25 m 或以下。
- 先用 CSG 制作灰盒,再烘焙;切勿为其添加动画。 Four Games(gIK02BgCCBI)和 PiCode
(S5kRpEKIh38 00:01:51):静态 CSG 的成本与建模几何体大致相当,移动 CSG 则很慢;成本取决于操作对象(移动时,切割一个 128 段球体的成本是切割一个方盒的 1,000 倍)。
CSG 需要封闭网格:开放的
CSGMesh3D操作对象会被静默忽略,不会报错。 - 道具优先使用简单碰撞形状。 Four Games(00:05:37)偏好使用
-colonly生成手动形状。 Trimesh(-col)仅用于静态关卡几何体;道具和任何动态物体使用方盒或凸形;参考几何体使用-noimp。 - 后导入脚本可在场景树之外运行。 Allard(5fDuf2IlizU 00:11:14):设置所有者,使用
局部变换,并使用
reparent(node, false);在脚本中设置碰撞层,以免遗漏(00:15:15)。已复现:未设置所有者的节点不会被保存,global_transform会返回单位变换,默认的reparent()会将位置归零。 - 弹簧臂搭配球体,并排除玩家。 Octodemy(ZCb12AHKMfE 00:07:40,00:08:35):
使用半径为 0.3 的 SphereShape3D、
top_level枢轴,以及add_excluded_object(player)。弹簧臂会在距墙壁一个半径处停止。 - AI 生成的 GLB 文件应视为已标准化的占位资源,除非清单另有说明。 通过场景交付的 Tripo、Meshy 和 Hitem3D 文件,其单位盒大小、枢轴居中、双面、金属度 1.0、4K 贴图以及 15k 至 1M 个三角形。Jan(L5emNlNYVfY 00:02:00,供应商)会先将网格重新拓扑至 6k 至 8k 个三角形。尺寸、枢轴、朝向、碰撞和预算由导入脚本应用的清单决定。
- Terrain3D:检查区域布局,准备纹理,并保存为二进制格式。 Tokisan(oV8c9alXVwU
00:20:22):区域放置不当会大幅增加内存占用。在 1.0.2 中,以原点为中心、大小为 1,024 m 的地形,使用 256 的区域尺寸时需要 16 个区域,使用 512 时需要 4 个区域(分配 1.05 km²),但使用 1,024 时需要 4 个区域(4.19 km²)。
纹理应无缝、为正方形、尺寸为 2 的幂次方、大小相同、通道打包(反照率加高度、法线加粗糙度),且全部采用相同的压缩方式(00:04:33;Four Games ejlD8cM9kk4 00:10:06)。保存为
.res,因为.tres加载较慢(YtiAI2F6Xkk 00:01:30)。 - 交付可运行代码,并注明测量数据。 如果计划是交给没有这套工具的人使用,就应提供辅助工具运行的 GDScript(procedures.md 中有),而不只是
gd_world.*调用。此处测得的数值是 M 系列 Mac 上的效果大小:请明确说明,并在目标设备上重新测量。
分歧:使用胶囊体(GDQuest)还是圆柱体(Juli,U5A_JArREUc):胶囊体对边缘的容错性更好,圆柱体则能提供更干净的贴墙奔跑和滑行法线。使用 CharacterBody3D(GDQuest、Juli)还是 RigidBody3D (Bramwell,sVsn9NqpVhg):只有当玩家必须是受物理模拟的对象时才使用 RigidBody。
首先确定
| 输入 | 对方案的影响 | 默认值 |
|---|---|---|
| 相机 | 弹簧臂或头部枢轴 | 第三人称,弹簧臂 4.5 m |
| 角色尺寸 | 胶囊体决定门、台阶和走廊尺寸 | 半径 0.35,高 1.8,台阶 0.45 |
| 关卡类型 | GridMap 套件、Terrain3D 或默认高度图 | 先制作白盒,再使用套件 |
| 世界尺寸 | 精度和流式加载 | 单精度(float32 在 1 km 处步长为 0.12 mm,在 8 km 处为 1 mm);当经过性能分析的最差视图或加载时间超出预算时再进行流式加载,而非按固定尺寸触发 |
| 资源来源 | Blender 后缀或 AI GLB 清单 | AI GLB + 清单 |
| 目标平台 | 渲染器、预算、压缩 | 桌面端 Forward+;Web 和移动端 Compatibility(Juli 00:24:02) |
| 物理引擎 | 自 4.6 起默认为 Jolt,但仅适用于新项目 | Jolt,由门禁检查 |
工作流
- 项目门控(P1)。
gd_world.physics_gate(P)验证引擎:使用 Jolt 时,凹形状上的射线会返回 face_index -1(Godot Physics 返回 8)。手写的 project.godot 会使用 Godot Physics。使用set_layer_names命名图层。门控条件:engine_running为 "Jolt Physics",且无标志。 - 玩家(P2)。 先运行
build_player,再运行controller_suite(无头模式,--fixed-fps 60)。门控条件:速度达到 move_speed;低头时速度相同;跳跃顶点与 v²/2g 相差不超过 0.1 m;能上到 max_step_height 的台阶,并拒绝更高的台阶;到达边缘时不吸附;能上 40 度坡,不能上 50 度坡;手臂在墙边会缩短。 - 白盒搭建(P3)。 离线运行
validate_layout(layout),然后运行build_village、door_test并烘焙。门控条件:每扇门都能让实际胶囊体通过(0.70 m 会阻挡,0.72 m 可通过,r 为 0.35;离线规则要求 1.00 m[增加了余量]),烘焙后的三角形数量与 CSG 三角形数量相等,截图呈现出预期效果。 - 组件套件(P4)。 运行
build_kit、build_grid、stairs_walk。材质应用于网格表面,每个组件包含一个 StaticBody3D 和一个 NavigationRegion3D(参见文档)。在构建库之前设置光照贴图纹素尺寸(根据文档,GridMap 自动生成的 UV2 使用 0.1,不再重新测量;.import 默认值为 0.2),并让导航网格单元格尺寸与地图的 0.25 保持一致(参见文档)。门控条件:每个已使用的单元格都有射线命中,且玩家能爬上每个楼梯组件(3 m 层高需要 8 级台阶;6 级会被阻挡)。 - 地形(P5、P6)。 小型世界:运行
build_island(分块 ArrayMesh 加一个 HeightMapShape3D),然后运行collision_check。雕刻或绘制的世界:使用gd_world.terrain3d,通过change_region_size()设置区域大小(直接设置region_size会被忽略),并按区域对齐放置。绘制是人工步骤:先在大块且一致的区域绘制底色,再喷涂;切勿在自动着色器区域上喷涂(YtiAI2F6Xkk 00:05:45 至 00:07:25)。门控条件:400 条射线的碰撞误差在 0.1 m 以内;记录区域数量和尺寸;存在.res数据;截图已打开。 - 散布(P7)。 运行
gd_world.scatter,始终使用窗口模式。门控条件:每个实例都落在地面上;.tscn 中每个 tile 都有一个buffer;统计拒绝数量;检查关闭前的截图。 - 从 GLB 导入道具(P8)。 离线运行
glb_stats和glb_flags,然后运行ingest_glbs(P, drop, manifest)(预先编写 .import,包含 LOD、阴影网格和光照烘焙,使用post_import_prop.gd,将纹理重新调至 VRAM 的 2048),然后运行audit_props和lod_probe。资源正面为 +Z(Vector3.MODEL_FRONT);look_at(t, up, true)会将 +Z 转向目标。Blender 导出的模型已三角化、应用变换,骨架处于静止姿势(参见文档)。门控条件:清单中的高度正确;底部位于 y 0;背面剔除已启用;了解预算标志;与 1.8 m 参照物并排的截图;朝向已检查。 - 流式加载(P9)。 使用
runtime/cell_streamer.gd,unload_radius大于load_radius,并通过world_stream.gd:walk在窗口模式下测试。门控条件:在边界上请求节流次数为 0;结束时每个单元格均已卸载,节点数量恢复至基线;最差帧耗时在预算内。 - 审计与性能分析(P10)。 运行
audit_level(scenes),然后运行gd_run.profile_scene(..., driver="vulkan")。门控条件:没有残留 CSG、无头 MultiMesh 或未命名图层;记录 GPU 毫秒数和绘制调用数。窗口模式下的帧时间受显示器刷新率限制,因此应以 GPU 和 CPU 毫秒数作为评判依据。
数值
| 数值 | 测量结果或来源 | 对照基准 |
|---|---|---|
| 控制器默认值 | 速度 6、加速度 40、空中控制 8、跳跃 5.5 m/s、下落上限 30 | 本工具包 [新增],GDQuest 形体 |
| 楼梯模块 | 可攀爬 0.45,无法攀爬 0.6;上升高度为 0.10 / 0.25 / 0.45 时,下降过程中处于空中的帧数分别为 120 帧中的 0 / 8 / 49 帧 | 踏面 0.35,6 m/s |
| 下方地面射线 | 最大台阶高度的 1.5 倍 | Majikayo:0.5 时为 0.75 |
| HeightMapShape3D 误差 | 最大 0.058 m,平均 0.004 m | 双线性插值,间距 1 m 和 2 m |
| 散布 | 11.7 ms 内从 6,000 条射线生成 1,931 棵树 | 30 度坡度,净空 2 m |
| AI GLB 纹理 | 每张 4K 贴图从无损 19.6 MB 降至 S3TC 2.8 MB | 尺寸上限 2048,启用 mipmap |
| 1080p 下的 LOD | 灯塔在 30 m 处为 986,642 个三角形,在 300 m 处为 61,616 个 | mesh_lod_threshold 1.0 |
| 流式加载 | 无滞回时,240 帧内加载 69 次;启用后为 0 次 | 边界节奏控制,64 m 网格单元 |
| 水面 z-fighting,平面低 1 mm | Compatibility:近裁剪距离为 0.05 时占 1.7% 像素,0.25 时占 0%;Forward+:两种情况下均为 0% | Tokisan 近裁剪距离 0.25(YtiAI2F6Xkk 00:18:00) |
质量门槛
- 通过探针验证引擎,而非读取设置。图层均有命名。
- 每个可行走表面都有碰撞:对每个 GridMap 单元、房屋地板和地形采样点执行射线测试。
- 控制器测试套件通过,且使用项目实际的台阶和门尺寸。
- 已发布场景中不得有 CSG,不得有缩放过的碰撞形状(HeightMapShape3D 间距除外),不得有双面封闭网格。
- 通过带窗口的运行生成 MultiMesh 场景;审计可找到缓冲区。
- 道具尺寸符合清单,基座位于 y 0,碰撞简单,VRAM 中的纹理不超过 2048,LOD0 符合预算(LOD 不会降低 LOD0)。
- Terrain3D 数据采用
.res格式,区域数量符合要求,纹理遵循第 9 条中的规则。 - 已打开以下截图:村庄、工具包、岛屿特写、Terrain3D、道具陈列、楼梯。
常见错误
| 错误 | 症状 | 修复 |
|---|---|---|
| 根据胶囊体移动距离确定台阶高度 | 能爬上超过限制的台阶 | 将射线投向踏面 |
| 没有向下检测地面的射线 | 每经过一个边缘都会向下弹 | 先发射长度为台阶高度 1.5 倍的射线 |
| 无头运行散布操作 | 重新加载后树木消失;没有缓冲区 | 使用窗口化运行 |
update_map_data_from_image(img, -1000, 1000) | 10 m 变成 19,000 m | 像素读取范围为 0..1:使用 (0, 1) |
使用 FastNoiseLite.get_image 生成高度 | 出现阶梯状效果(8 位) | 使用浮点循环或 RF 图像 |
| 在摄像机之前添加 Terrain3D | "Cannot find the active camera" | 先添加摄像机,或使用 set_camera() |
在调用 add_child 前设置 Terrain3D.collision_mode 或 region_size | 设置被忽略 | 在场景树中调用 collision.set_mode()、change_region_size() |
| 区域尺寸超过地形尺寸且以原点为中心 | 内存占用变为 4 倍 | 使用 256 或 512,或与区域网格对齐 |
| 地板和墙壁共用一个 GridMap | 墙壁替换了地板 | 使用第二个 GridMap |
在 _post_import 中调用 reparent() | 子节点跳到原点 | 使用 reparent(n, false) |
| 移除后缀时名称发生冲突 | @StaticBody3D@19793 | 使用唯一的基础名称 |
| 认为 LOD 足以处理 100 万三角形的 GLB | 距离 30 m 处仍有 98.6 万个三角形 | 导入前先进行简化 |
| 水面与地面共面 | Compatibility 渲染模式下闪烁 | 设为接近 0.25,或偏移水面 |
移交
- scenario-godot-expert:工具包、审查循环、版本陷阱。
- scenario-godot-rendering-lighting:光照贴图、遮挡体、GI、雾(深度雾可以隐藏流式加载边缘 [已添加])、阴影。
- scenario-godot-shaders:地形混合或三平面着色器、水体。
- scenario-godot-animation:绑定骨骼的角色和导入的动画。
- scenario-godot-gameplay:导航烘焙、AI、交互。
- scenario-godot-pipeline-automation:批量导入、CI、
post_import_prop.gd以外的插件。 - scenario-godot-performance-export:平台预算、Web 和移动端导出、合并的远距离单元代理(HLOD)[已添加]。
- blender skills:Blender 标记在导入时被替换(Allard 00:04:38);仅当保存依赖文件时才会刷新链接数据(00:27:49);用于 AO 的 "glTF Settings" 节点组(FinePointCGI PIpCl6TYnC0 00:03:23)。
- scenario-3d:生成 GLB。面向客户的文本中写上 "Scenario MCP"。
Godot 4.7 说明
- Jolt 是 4.6 及更高版本新项目的默认选项;手写的 project.godot 需要设置
physics/3d/physics_engine="Jolt Physics"。 - 观察到的场景 .import 键:
meshes/lightmap_texel_size为 0.2,gltf/naming_version=2,各节点物理设置位于_subresources中。预先编写的最简 .import 文件会生效。 - 无头模式下的
--import会保留提取出的 glTF 纹理的无损质量;重新调整流程会设置 VRAM。 SurfaceTool.set_smooth_group(-1)会生成平面法线。- 脚本 API 中没有
LightmapGI.bake或OccluderInstance3D.bake。 - Terrain3D 1.0.2 可在 4.7.2 中加载;第一次运行
--import时崩溃(信号 11),第二次运行正常。
参考资料
references/procedures.md:P1 至 P10,包含代码、实际结果和数据。references/expert-notes.md:各位专家的说法、对应时间戳,以及与 4.7.2 不一致之处。references/critique.md:基准和评分答案中的错误,以及此技能的局限。references/gui-paths.md:仅通过视口操作时的编辑器路径,以及对应的代码替代方案。references/sources.md:视频、文档、插件和版本。