Skip to content

按现象排错 ​

从没日志、找不到球、计分错误和 HUD 不更新等现象,找到下一步检查。

先选与你看到的现象最接近的一项。每次改一个原因,重新开始一次试玩并重复原操作;不要一边修名字,一边改物理、事件和计分规则,否则难以知道哪一项起作用。

改了代码,却没有变化 ​

  1. 确认改的是当前教程工程的 client/main.lua 或 server/main.lua,不是下载目录里另一份同名文件。
  2. 保存文件,在编辑器里确认同步的确完成。使用开发助手与使用 CLI 的同步流程不同,以第一课中与你工具一致的路径为准。
  3. 先修改一条日志里的独特文字,重新试玩,确认看到这句新文字。
  4. 仍然看到旧文字,就先处理工程绑定或同步,暂时不要继续调玩法。

本地文件保存成功不等于编辑器内存中的代码已经更新。停止试玩后再改代码,重新运行时只看这次会话的日志。

一条日志都没有,或只看见一端 ​

检查预期不符合时
地图模式世界版 / SE回到世界版教程地图
文件位置client/main.lua 与 server/main.lua修正目录和文件名
当前状态已进入试玩启动本次试玩后再查输出
输出来源能区分 client 与 server选择对应输出来源,清除过滤条件
第一条错误没有入口加载错误先修第一条错误,再重跑

入口还未正常执行时,先恢复第一课检查点。后面的碰撞、HUD 或存储都不能替代这项检查。

报错里出现 nil ​

这通常说明代码想使用一个当前没有取得的值。看报错指向哪一个变量,再检查它的来源。

变量来自哪里首先检查
场景查找Name、类型、父子层级与是否递归查找
Players.LocalPlayer当前是不是 client,本地玩家是否已就绪
player.Character角色是否尚未生成,重生后是否仍持有旧引用
PlayerGui/EuiManagerUI 是否准备完成、是否重新读取当前对象
require 返回值模块是否 return 正确对象、路径是否存在
异步加载/存储是否在完成回调前读取,是否处理失败

判空并输出原因能让程序停止在明确位置,但不等于问题已经修好。随后仍要修正名称、等待条件或调用时机。

找不到球体、方块或特效 ​

  1. 在场景树里点击对象,逐字核对脚本使用的 Name,包括大小写、空格和中文字符。
  2. 核对具体类型:球体和方块应是本课指定的 WorldUnit,同名的 GroupUnit 不能替代它。
  3. 核对对象放在哪里。只查 World 的直接子节点时,放进分组后就可能查不到;按场景树专题确认获取链。
  4. 按场景搭建恢复当前检查点的对象树,再重试。

特效是可选表现时,应只影响表现。不要为了让日志安静,把计分流程改成“必须取得特效才运行”。

球推不动,或碰上目标没有日志 ​

先不看分数,确认最小碰撞是否成立。

  1. 球是否是动态物理对象,物理模拟是否启用?静态物体(Static)不会按推球预期移动。球体质量(Mass)是否过大(建议设为 1)。本教程球体原点位于模型底部,Y=0 为正确落位;只有换用原点不同的素材时才需核对它是否陷入地板。
  2. 地面、球、方块的位置与碰撞形状是否正确?眼睛看到的渲染模型不一定等于碰撞模型。
  3. 目标是否允许物理碰撞和碰撞事件?按当前课的属性表检查,避免凭名称猜设置。
  4. 事件是否绑定在预期方块上?先看当前碰撞对象的名字,再判断它是不是那一颗球。
  5. 是否因初始化错误提前 return,导致连接根本没建立?

先恢复第二课的命中日志,再接回计分。排错时不要再注册第二套会加分的监听。

一次命中加很多分,或一直只显示 1 ​

现象优先检查
连续抖动时刷分是否在 server 做了有效命中防抖
同一次碰撞固定加两次是否安装了两个入口,或重复初始化后旧 Connection 未断开
每次都回到 1是否在每次回调内把 score 初始化为 0
第二局出现上一局分数回合重置是否清理状态,旧定时回调是否已失效
加入诊断后分数改变诊断是否误执行加分;临时日志应只读

从每次命中只算一次重新核对。需要临时监听时,保存并断开其 Connection;计分只能由一条已经定义清楚的权威链修改。

得分记错人,或下一局没碰球也得分 ​

先确认服务端记录的是哪位玩家、何时记录、何时消费或清除。

  • 碰撞对象不是 Player。必须先证明它是 EggyUnit,再通过公开的角色反查接口取得玩家;查不到就不补造归属。
  • 玩家离开、新回合开始、一次归属已消费时,要按当前主线规则清理记录。
  • 不接受客户端直接传来的“玩家身份 + 分数”当作事实。
  • 单客户端能计分,只证明了单人链路;两人轮流触球必须另做双客户端验证。

回到玩家归属。

服务端分数变了,HUD 没有变化 ​

按数据流从前往后检查,不要同时改每一端。

检查点应该看到什么下一步
服务端计分当前玩家的新分数没变先修计分
服务端下发完整快照发给对应玩家确认事件定义与目标
客户端接收当前回合与分数确认先监听后请求,事件名一致
客户端校验载荷字段与类型符合协议比对同一版本的 common 文件
文本节点查找当前 PlayerGui 下找到正确 EUITextLabel核对 Name、类型、就绪与重试
文本赋值与画面数字更新且可读检查 Visible、位置、尺寸和遮挡

先按通信课用客户端日志显示结果,再查HUD 课。同时复制通信专题和主线入口可能重复发送请求或绑定监听,应保留一套完整工程。

按钮点了没反应,或进行中也能重开 ​

先判断是“按钮没有产生输入”,还是“服务端正确拒绝了当前请求”。

  1. 节点是否是正确的 EUIButton,名称是否与当前课一致?
  2. 初始化是否成功,点击 Connection 是否建立?
  3. 客户端是否只发请求,服务端是否收到?
  4. 当前是否处于允许重开的结算阶段,载荷是否符合协议,是否被节流?
  5. 一次结算已经接受过重开后,重复请求应被拒绝,不重复开始新局。

不能用“按钮里直接清分数”来绕过服务端规则。对照再来一局的有效请求与无效请求验收。

音效或特效没出现 ​

先确认基础计分仍然成功,再独立检查表现资源。

  • 音频 URI 必须是当前项目可访问的真实音频,不能把 mesh/preset 当音频。
  • EffectUnit 先在编辑器配置资源和稳定名称,代码只查找并控制它。
  • 同一特效连续使用时,旧延时回调不能把新一轮播放提前隐藏。
  • 确认要给谁看或听:本地反馈和全场反馈应选择相应运行端,并分别验证。

回到让游戏更有反馈。音效不可听、截图不可见时,不把一条“播放”日志当成效果验收。

最后保存一条能复现的记录 ​

不需要复杂格式,写清这些就够:

  1. 使用哪个检查点和工程版本。
  2. 从重新试玩开始,按什么顺序操作。
  3. 原本期待什么,实际看见什么。
  4. 当前会话的第一条相关错误或关键日志。
  5. 只改了哪里,重跑后结果如何。

想进一步使用 CLI、testspec 或回归清单,查测试与调试专题。恢复成功后回到主线继续当前课。