前 45 天我们几乎都在 2D 世界里打转:瓦片地图、2D 物理、像素完美渲染。但走 Steam 的独立游戏里,3D 是绕不开的一大类——今天第一次跨到 3D。好消息是,Godot 的 2D 与 3D API 高度相似:Node3D 之于 Node2D,CharacterBody3D 之于 CharacterBody2D,大部分节点都是「同款不同维」,所以你不是从零学一门新引擎,而是把已有知识加一个 Z 轴。坏消息是:那个多出来的 Z 轴,会让很多在 2D 里「想当然」的做法直接翻车。

今日速览

  • 2D 与 3D 的 API 几乎一一对应:官方明确说 3D 平台跳跃、3D 运动学角色的教程与 2D 版「几乎一模一样」,迁移成本比想象中低。
  • 别再用 rotation 属性:官方《Using 3D transforms》直接点名——游戏里不要用 Node3D 的 rotation,改用 Transform3D / Basis,否则会遇到万向锁与插值反向。
  • 3D 光照有数量上限:Forward+ 渲染器用聚类(clustering)做实时灯光,当前相机视野内默认最多 512 个聚类元素(点光/聚光/贴花/反射探针都算),超了要调 Max Clustered Elements。
  • Z-fighting 是 3D 头号「玄学 bug」:两个物体共面时贴图会闪烁,根治办法是把相机的 Near 值调大,让深度缓冲精度集中在可视范围内。
  • 纹理别超过 4096×4096:移动 GPU 普遍只到 4096,桌面老设备 8192 也可能不支持;需要重复平铺的纹理请用 2 的幂尺寸。

核心学习内容

一、坐标系与变换:3D 的第一个坑

2D 里一个 rotation(弧度)就能表达朝向,到了 3D 就不行了。官方文档把 Euler 角(X/Y/Z 三个角度)的三个致命问题讲得很清楚:

  1. 旋转顺序不唯一:先绕 X 再绕 Y,和先绕 Y 再绕 X,得到的结果不同。文档用第一人称控制器举例——鼠标左右控制水平视角、上下控制俯仰,必须先在 Y 轴(Godot 是 Y-Up)旋转,再在 X 轴旋转,反了效果就错。
  2. 插值会走反方向:在两个朝向之间插值,用角度去插可能让相机朝相反方向转(270°→0° 不等于 270°→360°)。
  3. 万向锁(Gimbal lock):两个旋转轴对齐时,会丢一个自由度。

结论很直接:游戏逻辑里不要碰 rotation,用 look_at()、Basis 和 Transform3D。rotation 主要留给编辑器里做单轴微调。理解这一点,能帮你避开 3D 里一大半「视角诡异」的 bug——而且这正是 DeepSeek 最容易写错、需要你用提示词纠正的地方。

二、搭一个「能看」的 3D 场景

选中 Node3D 节点后,编辑器会自动切到 3D 工作区。几个必记快捷键:Q 选择 / W 移动 / E 旋转 / R 缩放;T 切换本地坐标系,Y 开启吸附,F 把相机聚焦到选中物体——F 是 3D 新手最该记住的一个键,迷路时按一下立刻回正。

一个最小可看的 3D 场景通常包含:

  • MeshInstance3D:挂一个几何体(Box/Capsule 等)+ StandardMaterial3D,先有个「东西」。
  • Camera3D:玩家的眼睛。注意不要把它放进会被脚本随意 rotation 的节点。
  • WorldEnvironment:管环境光与背景,没它场景会黑得看不见。
  • 光:DirectionalLight3D(太阳,有方向、照亮全场)、OmniLight3D(灯泡,向四周)、SpotLight3D(手电/聚光)。每个光都有 Color、Energy 等通用参数;Energy 可配合 HDR 做「过曝」感。

三、3D 的性能与「玄学」红线

  • 光照别乱堆:Forward+ 下每个点光/聚光/贴花/反射探针都占一个聚类槽位,视野内默认上限 512。做室内小场景够用,但别用几十个点光去做「氛围」,该用烘焙(LightmapGI)就用烘焙。
  • Z-fighting:物体共面时贴图闪烁,根因是深度缓冲精度有限。把相机 Near 值调大可以显著缓解(代价是太近的物体可能被裁掉),所以要按场景尺度权衡。
  • 色带(banding):3D 默认 HDR 内部渲染、输出到低精度缓冲,平滑渐变上会出现一圈圈色带。打开 Project Settings → Rendering → Anti Aliasing → Use Debanding 即可,几乎零成本。

🎯 DeepSeek 提示词

三条围绕「3D 入门」的实操提示词。核心思路:把官方踩坑点写进约束里,逼 DeepSeek 一开始就写对,而不是等你 debug。

提示词 1:生成 Godot 4 第三人称角色控制器(避开 rotation 坑)

适用场景:第一次写 3D 角色控制,想要一份能直接跑、且视角不会「发疯」的脚本。

你是 Godot 4.x 的资深 GDScript 工程师。请为我写一个基于 CharacterBody3D 的第三人称角色控制器脚本。

【任务】实现:WASD 相对摄像机方向的移动 + 鼠标控制视角(水平环绕、垂直俯仰)+ 跳跃(受重力)+ 简单地面检测。

【强制约束】
1. 绝对不要使用 Node3D 的 rotation 属性来做朝向;水平转向用 rotation.y 之外的方案(推荐用 Basis/Transform3D 或对相机 pivot 使用四元数思路),并用文字说明为什么。
2. 俯仰角必须 clamp,比如限制在 -70°~70° 之间,防止翻转。
3. 使用 move_and_slide(),重力用 get_gravity() 或常量,地面检测用 is_on_floor()。
4. 输入统一读 InputMap 动作名:move_forward/move_back/move_left/move_right/jump,不要硬编码按键。
5. 所有变量加类型注解(GDScript 静态类型),变量名用 snake_case。

【输出格式】
(1) 完整 .gd 脚本,用代码块给出;
(2) 一段注释:每个 @export 参数的作用与建议初值;
(3) 场景节点树建议(父节点/子节点层级);
(4) Read the docs:3 条容易再踩的坑。

【额外要求】最后用 3 句话解释「为什么官方建议游戏里别用 rotation」。

提示词 2:诊断「3D 旋转/插值」类 bug(Debug 模板)

适用场景:视角插值走反、相机突变、朝向抽搐——3D 里最典型的几类玄学 bug。

你是 Godot 4 的调试专家。我在做 3D 游戏时遇到一个旋转相关的 bug,请帮我定位。

【现象】<粘贴:相机/角色在你操作时具体怎么表现,例如「鼠标上下移动时视角左右乱转」「用 Tween 插值相机朝向时会绕远路」>
【相关代码】<粘贴涉及 rotation/lerp/tween/look_at 的代码片段>
【我的引擎版本】Godot 4.x

【分析要求】
1. 先判断这是不是 Euler 角问题(旋转顺序 / 插值 / 万向锁)或坐标系问题(局部 vs 全局、Y-Up)。
2. 给出最小可复现的解释,并指出代码里哪一行是根因。
3. 用 Transform3D / Basis / look_at() / quaternion 给出修复版代码。
4. 说明如何验证修好了(可观察的现象)。

【输出格式】分「根因一句话」「为什么」「修复代码块」「验证方法」四段。若信息不足,先列出你需要我补充的内容再给结论。

提示词 3:搭一个不翻车的 3D 场景与光照方案

适用场景:从空场景开始,想一次性把相机/环境/灯光/性能配好。

你是 Godot 4 的 3D 场景搭建顾问。我要做一个 <类型,例如 小型室内恐怖探索> 的 3D 场景,目标平台是 PC(Steam)。

【任务】请给出这个场景的「节点树 + 光照 + 环境 + 相机」配置方案。

【强制约束】
1. Forward+ 渲染器下,实时灯光(OmniLight3D/SpotLight3D + 贴花 + 反射探针)在相机视野内的聚类元素总数要控制在 512 以内;若方案需要更多,请改用 LightmapGI 烘焙并说明取舍。
2. 相机必须给出 Near / Far 的建议值,并解释为什么这样能减少 Z-fighting。
3. 打开 Use Debanding 消除色带。
4. 所有纹理尺寸不超过 4096×4096,需要平铺的用 2 的幂。

【输出格式】
(1) 缩进表示的节点树(节点类型 + 关键属性);
(2) 灯光清单表格:类型 / 位置 / Color / Energy / 阴影开关 / 理由;
(3) 一段「性能与画质取舍」说明(≤150 字)。

【约束】不要给我泛泛的「注意性能」,每条建议都要能落到具体节点或具体参数值上。

学习心得

到今天,我们手里其实已经有两条路了:2D 用像素/瓦片,3D 用节点/变换。3D 最大的诱惑是「看起来更高级」,但官方文档反复提醒的却是稳定性——别用 rotation、控制灯光数量、处理 Z-fighting。这恰恰说明:3D 的难点不在「画得出来」,而在「跑得稳、不抖」。

对「用 DeepSeek 做一款 Steam 游戏」这个目标来说,今天的收获是:3D 的坑大多是「结构性」的,可以在写第一行代码前就用提示词规避。我在提示词里把「不许用 rotation」「灯光控制在 512 以内」「给出 Near/Far 建议」写成硬约束,DeepSeek 产出的代码就直接绕开了这些雷——这比事后 debug 省太多时间。下一步就是把 2D 已经练熟的「移动 → 碰撞 → 相机 → 存档」套路,整体平移到 3D,你会发现大部分节点只是名字从 2D 换成了 3D。

明日关注

  • 用 Godot 官方 3D 平台跳跃/运动学角色教程,把一个 2D 角色控制器「翻译」成 3D,对比节点差异。
  • 在本机搭一个最小 3D 场景(Node3D + MeshInstance3D + Camera3D + DirectionalLight3D + WorldEnvironment),跑通并截图。
  • 让 DeepSeek 用「提示词 2」的诊断模板,检查一个故意用 rotation 写的相机脚本,看它能否准确指出万向锁根因。

本文由自动化学习流水线每日生成,坚持即学即记。