看懂报错,而不是让 AI 整份重写
从第一条错误、调用栈和运行时变量开始缩小问题。
01三类问题,三个入口
| 现象 | 先看哪里 | 常见例子 |
|---|---|---|
| 脚本不能解析 | 第一条解析错误及所在行 | 类型冲突、缩进、拼错函数 |
| 运行时出错 | Debugger 的调用栈与变量 | 空引用、错误节点路径 |
| 没有报错但行为错误 | 断点、状态、输入链路 | 重复触发、错误旗标、UI 没更新 |
报错串中后面的错误可能是第一个错误的连锁反应。优先修复最早且最具体的原因,而不是把所有错误一次性贴给 AI 后接受大规模改写。
02用一行故障练习排查
extends Node
func _ready() -> void:
var missing: Node = get_node_or_null("MissingNode")
if missing == null:
push_error("练习:找不到 MissingNode;请检查子节点名称")
return
print("找到节点:", missing.name)- 挂到空 Node 并运行,读到明确错误。
- 添加名为 MissingNode 的子节点,重新运行确认错误消失。
- 改动名字再次复现。用“节点不存在”解释原因,而不是说“Godot 随机坏了”。
03断点与 Remote 场景树
在目标语句旁设置断点,运行到那一行后看变量值与调用栈。编辑器里的 Local 树是编辑状态;Remote 树用于观察正在运行的场景。确认真正运行的是哪份实例,特别是出现“改了参数却不生效”时。不要把 print 无限放在每帧循环里,日志洪水会盖住关键事件。
04给 AI 的故障报告
范围:独立练习场景 debug_practice.tscn
复现:F6 后立即出现错误
预期:输出找到节点
实际:push_error 提示找不到 MissingNode
证据:第一条报错、调用栈、实际节点树
已检查:脚本已保存;运行的是当前场景
请求:只定位原因并给最小修复,不改其它文件05先稳定复现,再减少变量
如果问题是“有时按键没有反应”,先把“有时”换成一段固定操作,例如启动后向右走、打开面板、关闭面板、再按调查键。连续重复这条路径,记录失败发生在哪一步。无法稳定复现时,补充窗口焦点、操作间隔和场景切换等条件,不要立刻改很多代码;每多改一项,就少一份判断原始原因的证据。
接着缩小实验:保留一个玩家、一个交互物和一个面板,其他练习对象先在副本场景中移出测试路径。目标不是删除正式功能,而是找到能出现同一问题的最小条件。若小场景不再出错,这也是新证据,说明差异可能在多实例、重叠范围或流程协调。把“缩小后是否还会发生”写进报告,不要只上传最后一张报错截图。
06断点停下来以后,优先看这三件事
断点不是一个红点装饰。程序停住后,先看当前函数为什么被调用,也就是调用栈;再看决定分支的变量实际值;最后确认当前对象是否是你以为的那份实例。假如界面显示旧文本,而变量已经更新,问题可能在你修改了隐藏面板,不是赋值语法错了。把对象名称和关键值一起记录,比单独说“变量正常”更有用。
不要在不知道状态的情况下连续按继续,试图碰到答案。可以在一个关键判断前停住,预测下一步应该进入哪条分支,再执行并对照。如果预测不符,先修正对条件的理解。若预测正确而结果仍错,把断点移到下一条边界。这样每轮排查都能排除一段链路,而不是不断增加分散的日志。
07修好以后,要证明没有把问题换个地方
最小修复完成后,先重跑最初那条失败路径,再补一条相邻路径。例如修复关闭对话后不能移动,除了确认可以移动,还要验证对话打开期间仍不能移动;否则可能只是彻底取消了输入锁。修复重复触发后,还要确认重置练习后可以再次触发,不能把所有后续操作永久屏蔽掉。
给这次问题写五行收尾:可复现步骤、根因、实际修改位置、修复后观察、尚未覆盖的范围。根因应是“关闭回调没有恢复输入状态”这样的具体关系,而不是“引擎抽风”。如果仅做了脚本解析检查,就写脚本检查通过,不写交互已经正常。经过这一步,你留下的不只是一个暂时能用的版本,也是一份以后遇到相似问题时可以复用的判断方法。
动手后,再勾选
不是“我看懂了”,而是你在独立练习里做出并检查过。
换一个情景,你会怎么判断?
编辑器没有报错,但一个点击触发两次,先做什么?
用自己的话,留一条笔记
可以写“我之前以为……,现在发现……”,或者记录还没解决的问题。
↗回到资料核对
本课是解释与练习,不替代对应版本的官方手册。网页实验不运行 Godot;未标明实机验证的代码,仍需在独立工程中检查。
标记已读不会自动勾选实作,也不代表游戏功能已经完成。