主题
场景与界面准备
用固定名称、位置和物理属性搭好推球撞方块;第七课再加入界面。
本页是所有阶段包共用的场景说明。第 01 课只需能启动的 SE 地图;从第 02 课开始准备球体和方块;第 07 课再做文字,第 08 课再做按钮。
工程、同步与试玩
第一次使用 Lua 时,先做这一节。地图文件、磁盘上的 Lua 工程、编辑器本次试玩所用的代码,是需要保持同步的三处内容。
- 新建并保存一张专用的世界版地图。打开 LUA → 蛋仔开发助手 → 生成工程,选择一个空的本地文件夹,用 VS Code 打开生成的目录。
- 在文件树找到
server/main.lua和client/main.lua,按当前课替换内容,保存文件。工程里的official、.codemaker、.vscode、_trigger等原生目录保留;阶段包只覆盖 README 列出的 Lua 文件。 - 在开发助手中确认连接的地图名称正确,并确认同步完成。不同版本的按钮文字可能不同,以当前插件状态为准。 不确定插件是否同步时,可使用下方 CLI 流程,得到明确的校验和推送结果。
- 在编辑器开始试玩,打开试玩画面左上角的日志入口,搜索
[推球]。同时核对消息的client/server标记;不要被上一次试玩的旧消息误导。 - 要改代码时,先退出试玩,再保存、同步、重新试玩。把第一课的一句文字改掉并看到新文字,是确认整条同步链路的最小检查。
已安装 Editor CLI 时:可复现的同步方法(Windows PowerShell)
只有一个编辑器窗口打开时生成工程。CLI 0.16.5 的 code init 不支持同时打开多个编辑器;已经生成并绑定的工程不需要再次初始化。下面以“文档”目录下的 PushBallLua 为例;已有工程时,把第二行换成自己的实际工程路径,跳过 code init。
powershell
$tutorialCli = Join-Path $env:USERPROFILE '.eggitor\cli\editor-cli.exe'
$tutorialWorkspace = Join-Path $env:USERPROFILE 'Documents\PushBallLua'
& $tutorialCli code init --workspace $tutorialWorkspace --json用 VS Code 打开该目录,完成本课文件修改并保存后,先校验、查看推送计划:
powershell
& $tutorialCli code validate --workspace $tutorialWorkspace --strict --json
& $tutorialCli code push --workspace $tutorialWorkspace --dry-run --show-diff --json确认计划只涉及本课文件,再推送并试玩:
powershell
& $tutorialCli code push --workspace $tutorialWorkspace --json
$tutorialPlay = (& $tutorialCli play start --wait-ready --json | ConvertFrom-Json)
& $tutorialCli log grep '推球' --play-session $tutorialPlay.playtest_id --context 0
& $tutorialCli log trace --play-session $tutorialPlay.playtest_id --jsonlog grep 查找本次试玩的“推球”日志,log trace 提取错误;错误列表为空不代表两端日志已出现。客户端刚启动时可能稍晚就绪,可以再执行一次 log grep。推送结果中 deletions_skipped 应为空;有跳过项时先检查工程目录和绑定目标。--wait-ready 只证明服务端探针已就绪,仍需在日志中确认本课两端的输出。修改前停止试玩:
powershell
& $tutorialCli play stop --jsonCLI 路径不存在时回到开发助手流程,先完成当前工具的安装与连接;无需为了这套教程另写同步脚本。
先确认层级和名称
在场景树中让以下对象直接位于 World 下。名称必须完全一致,不能多空格,也不要保留重名对象。
text
World
├─ 大地板
├─ 出生点
├─ 球体 WorldUnit
└─ 方块 WorldUnit
“球体”和“方块”是对象名称,“WorldUnit”是类型。把一个空文件夹改名为球体不会得到物理球。
使用同一组资源和物理设置
在资源库放入球和方块,再在属性面板设置。资源 ID 用于核对素材;不需要把 ID 粘贴进 Lua。
| 对象 | 资源 | 位置 X、Y、Z | 物理类型 | 关键开关 |
|---|---|---|---|---|
| 出生点 | 空白地图已有出生点 | 0、0、0 | 保持模板设置 | 出生位置在地板上方可站立处 |
| 球体 | 球,official://preset/1701160 | -4、0、0 | Dynamic(动态) | 开启物理、碰撞、碰撞事件,质量 1 |
| 方块 | 方块,official://preset/105205 | -8、0、0 | Kinematic(运动学) | 开启碰撞、碰撞事件 |
保留资源原始大小。地板必须覆盖出生点、球和方块所在区域,并设为 Static(静态)、允许碰撞。空白地图自带的大地板可直接使用。
球沿 X 轴负方向推向方块。坐标中的 Y 是高度;这里的资源原点位于底部附近,Y 为 0 不代表把整个物体埋进地板。如果换用其他素材,请先检查它的原点、碰撞体和大小。
从上方看,三者排成一条线:
text
X 轴负方向 ←
方块 球体 出生点
(-8, 0, 0) (-4, 0, 0) (0, 0, 0)
← 玩家向方块推球第 02 课先验收场景
- 安装第 02 课脚本并启动试玩。
- 等待服务端出现“已找到球体和方块,等待碰撞”。
- 从出生点走到球后方,持续推动球朝方块移动。以画面里的方向为准,转动镜头后按键对应的世界方向会改变。
- 看服务端是否出现“球体碰到了方块”。
球不能动时先检查 Dynamic 和质量;球穿过去时检查双方碰撞;有接触却没日志时检查事件开关、对象名称,以及是否装了第 02 课的服务端脚本。
第 07、08 课准备界面
在普通 EUI 画布中创建两个文本节点;第 08 课再增加按钮。对象命名与节点类型如下:
text
普通画布:推球界面
├─ label_time EUITextLabel
├─ label_point EUITextLabel
└─ button_restart EUIButton(第 08 课增加)把时间、分数放在画面顶部能看清的位置,按钮放在它们下方。文本先分别填写“等待时间同步”和“我的分数:0”;按钮文字填写“再来一局”。按钮需要开启交互。
下面是一组已在试玩画面中核对过的布局。位置以画布左下角为原点;X 放在画布宽度的一半,Y 为画布高度减去顶部距离。
| 节点 | 宽、高 | 距顶部 | 字号 | 文字与背景 |
|---|---|---|---|---|
label_time | 460、56 | 110 | 36 | 深色文字 |
label_point | 460、56 | 168 | 36 | 深色文字 |
button_restart | 280、70 | 238 | 28 | 深色文字,浅色不透明背景 |
例如画布是 2286 × 1080 时,三个节点的 X 都是 1143,Y 分别是 970、912、842。三个节点的锚点都设为 0.5、0.5,文字居中对齐。使用水平居中比例约束、顶部绝对距离约束,不要同时保留左右边缘约束;这样改变窗口宽度后仍位于中间。
按钮字体请选择内置的“综艺体”。对应公开字体值是 hkxzyt_w9_gb.ttf,不带 font/ 前缀。实测中带前缀的默认字体值曾导致按钮有背景却没有字,改为内置字体并重新试玩后恢复。遇到相同现象,先检查字体选择,不必重写网络代码。
第 07 课启动后时间应自动更新;第 08 课在结束后显示按钮,点击后开启下一局。若仍显示编辑时文字,先核对名称和类型,再检查客户端日志。界面迟就绪时脚本会继续寻找节点。


两张图展示单人测试地图中的界面状态。按钮回调已经验证;真实鼠标、手机触摸区域仍需在目标设备确认,截图本身不能代替点击验收。
阶段包怎样使用
ZIP 包包含本阶段完整 Lua、README 和本页说明。它提供脚本快照,需要在编辑器中按本页搭建场景和界面。已有上一课地图时保留场景,按 README 更新脚本;从零开始时先建场景,再安装本阶段全部文件。
不要把不同阶段的 main.lua 混用。遇到问题先回到上一课已通过的阶段包,确认场景可以工作,再继续升级。
