5.5 实战项目:完整值一轮班的平台跳跃 本节摘要:这是全书的毕业项目:把前四章的零件总装成一个完整的 2D 平台跳跃游戏——有开始与死亡、有计分与重开、有对象池与打包产物。本节给出总装顺序、关键代码的拼装位置,以及把同一套骨架改造成射击、解谜、经营等类型的接口。 全书内容的总装顺序 前四章的案例散落在各节,本节把它们按依赖关系串成一条总装线。顺序有讲究:先立骨架(场景与管理器),再接玩法(输入物理),然后上表现(动画 UI 音效),最后接池化与发布——任何一步提前,都会在返工上花双倍时间。总装完成的项目结构如下: 场景:Menu(主菜单与开始按钮)、Level01(可玩的完整关卡)、常驻系统场景(叠加加载的全局管理器);
本节摘要:这是全书的毕业项目:把前四章的零件总装成一个完整的 2D 平台跳跃游戏——有开始与死亡、有计分与重开、有对象池与打包产物。本节给出总装顺序、关键代码的拼装位置,以及把同一套骨架改造成射击、解谜、经营等类型的接口。
前四章的案例散落在各节,本节把它们按依赖关系串成一条总装线。顺序有讲究:先立骨架(场景与管理器),再接玩法(输入物理),然后上表现(动画 UI 音效),最后接池化与发布——任何一步提前,都会在返工上花双倍时间。总装完成的项目结构如下:

前四章已经实现了所有零件,本项目真正的新代码只有一处:GameManager 的状态机。它把"死亡、重开、通关"从散落的回调收拢成一个有明确状态迁移的调度员:
using UnityEngine; using UnityEngine.SceneManagement; public class GameManager : MonoBehaviour { public static GameManager Instance { get; private set; } enum State { Menu, Playing, Dead, Cleared } State state = State.Menu; public int deaths; // 本局死亡次数,展示给结算页 void Awake() { // 单例加跨场景存活:常驻层的标准配置 if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); } public void StartGame() { state = State.Playing; deaths = 0; SceneManager.LoadScene("Level01", LoadSceneMode.Single); } public void NotifyDeath() { if (state != State.Playing) return; // 状态守卫:死亡事件只认进行中 state = State.Dead; deaths++; // 广播死亡事实(第 2.4 节的事件频道),UI 与音效各自响应 GameEvents.PlayerDied("player", deaths); // 两秒后自动重开,协程挂在常驻对象上不怕场景切换 StartCoroutine(RestartDelay()); } System.Collections.IEnumerator RestartDelay() { yield return new WaitForSecondsRealtime(2f); state = State.Playing; SceneManager.LoadScene(SceneManager.GetActiveScene().name); } public void NotifyCleared() { if (state != State.Playing) return; state = State.Cleared; Debug.Log("通关,死亡 " + deaths + " 次"); } }
尖刺与死亡区调用 NotifyDeath,终点旗帜调用 NotifyCleared。注意两个细节:状态守卫(NotifyDeath 只在 Playing 状态生效)挡掉了"死亡瞬间连续触发"的重复事件;重开计时用 WaitForSecondsRealtime,暂停或时间缩放为零时倒计时照走。
总装完成的验收不是跑分,而是扮演玩家完整走一遍动线:从启动到主菜单(按钮可点、音乐响起)、点开始进入关卡(加载有反馈不白屏)、移动跳跃踩板拾金币(手感与反馈齐全)、故意踩刺死亡(结算反馈加自动重开、死亡计数加一)、通关(结算页数字正确)、暂停退出(时间停摆、UI 可操作)、重进游戏(进度与设置保留)。每一步都对应前面某节的知识点,任何一步不对劲都能按章节回溯——这就是全书用一条主线案例的原因:排查路径和学习路径是同一条。
验收通过后按第 5.4 节流程出厂,产出 Android 安装包与 WebGL 版本。真机上如果发现编辑器没有的问题,优先怀疑三处:帧率差异暴露的时序 bug(回查 FixedUpdate 纪律)、分辨率适配(Canvas 锚点与安全区)、资源加载策略(Addressables 分组与首包体积)。
这套"常驻层加玩法层加表现层"的骨架可以直接改造成其他类型,替换的只是玩法层:
判断一个新玩法能不能装进这副骨架的标准:它是否仍然是"输入产生意图、物理或规则更新状态、表现层播反馈"的循环。绝大多数游戏都是,这正是"游戏循环值班室"这个视角的普适性。
值班演练到此完整收官。回头看这本教程的路线:认识值班室、领排班表、上物理岗与表现岗、进了调度科——下一次翻开别的 Unity 资料,你读到的将不再是零散的按钮说明,而是一间你早已熟悉布局的值班室。