5.5 实战项目:完整值一轮班的平台跳跃


文档摘要

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

5.5 实战项目:完整值一轮班的平台跳跃

本节摘要:这是全书的毕业项目:把前四章的零件总装成一个完整的 2D 平台跳跃游戏——有开始与死亡、有计分与重开、有对象池与打包产物。本节给出总装顺序、关键代码的拼装位置,以及把同一套骨架改造成射击、解谜、经营等类型的接口。

全书内容的总装顺序

前四章的案例散落在各节,本节把它们按依赖关系串成一条总装线。顺序有讲究:先立骨架(场景与管理器),再接玩法(输入物理),然后上表现(动画 UI 音效),最后接池化与发布——任何一步提前,都会在返工上花双倍时间。总装完成的项目结构如下:

  • 场景:Menu(主菜单与开始按钮)、Level01(可玩的完整关卡)、常驻系统场景(叠加加载的全局管理器);
  • 管理器:GameManager(游戏状态机:菜单中、进行中、已死亡、已通关)、ObjectPool(第 5.1 节的池)、AudioMixer 分组(音乐与音效两轨);
  • 玩法件:PhysicController(第 3.2 节)、CoinPoolable(第 5.1 节)、SpikeHazard 与 PressurePlate(第 3.3 节);
  • 表现件:AnimBridge 与三态状态机(第 4.3 节)、ScoreTextPunch 三件套(第 4.4 节)、烘焙光照与探针(第 4.2 节)。

项目总装架构

项目总装架构

动手:把状态机补完

前四章已经实现了所有零件,本项目真正的新代码只有一处: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 分组与首包体积)。

变式:同一副骨架的其他形态

这套"常驻层加玩法层加表现层"的骨架可以直接改造成其他类型,替换的只是玩法层:

  • 3D 射击:PhysicController 换成带鼠标视角的第一人称控制器,金币换成弹匣与准星反馈,状态机多一个"换弹中"状态——输入岗、物理岗、池化(子弹)全部复用;
  • 解谜游戏:把压力板机制扩展成核心玩法(多个机关的逻辑与门),物理保持低速,重点转向交互状态机与关卡数据结构(ScriptableObject 配置每关机关联动表);
  • 模拟经营:没有角色物理,玩法层换成 Tick 驱动的经济系统(定时结算收益),UI 层扩成主要表现面,对象池用于格子与票据刷新——事件总线的地位更加突出;
  • VR 应用:物理岗换成头显与手柄的追踪驱动,帧率指标提升到头显刷新率,交互从按键变成抓取与射线——但常驻层结构、池化、事件解耦、出厂流程一字不改。

判断一个新玩法能不能装进这副骨架的标准:它是否仍然是"输入产生意图、物理或规则更新状态、表现层播反馈"的循环。绝大多数游戏都是,这正是"游戏循环值班室"这个视角的普适性。

本节要点回顾

  • 总装顺序即依赖顺序:常驻骨架、玩法、表现、池化发布,顺序错了双倍返工;
  • 状态机加事件总线是全局调度件:状态守卫挡重复事件,Realtime 计时不受暂停影响;
  • 验收走玩家动线:启动到结算的完整链路,每一步对应一个章节的知识点;
  • 真机问题三优先:时序、分辨率、资源加载;
  • 骨架的普适性:换玩法层即可变射击、解谜、经营与 VR,值班循环不变。

值班演练到此完整收官。回头看这本教程的路线:认识值班室、领排班表、上物理岗与表现岗、进了调度科——下一次翻开别的 Unity 资料,你读到的将不再是零散的按钮说明,而是一间你早已熟悉布局的值班室。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U