基于 GameClientTrainning 项目(Unity 6000 + Entitas ECS),为前端工程师量身定制的渐进式学习路线。从零基础到能独立开发新模块,预计 2-3 周完成。
装好环境,跑起来,先玩 5 分钟感受游戏。不用看任何代码。
| 事项 | 做什么 |
|---|---|
| 打开工程 | Unity Hub → Add → 选 GameClientTrainning 目录,Unity 版本 6000.0.58f2 |
| 跑起来 | 打开 Assets/_Game/Scenes/Home.unity → 点 Play,先玩 5 分钟 |
| 通关一轮 | 从第 1 关打到第 5 关,观察:箭头怎么拔、撞击怎么扣血、通关特效、奖励弹窗 |
核心问题:从点 Play 到游戏画面,代码是怎么走的?预计 2-3 天。
从场景加载到 ECS 初始化到 Update 循环。
| 文件 | 看什么 | 路径 |
|---|---|---|
| HomeRoot.cs | 主菜单入口,加载 HomeScreen 预制体 | Assets/_Game/Home/HomeRoot.cs |
| GameRoot.cs | 游戏入口:创建 ECS 世界 + Feature + 所有 View | Assets/GameBase/App/GameRoot.cs |
| GameEnv.cs | 看哪些东西在运行时被持有(Camera、Root、预制体) | Assets/GameBase/App/GameEnv.cs |
| GameFeature.cs | 最重要:所有系统的 Add 顺序 = 执行顺序 | Assets/GameBase/App/GameFeature.cs |
能画出 "Play → GameRoot.Awake → GameFeature.Initialize → Update 循环" 的流程图。
Component 存数据,System 改数据,Entity 组合数据。
| 概念 | 前端类比 | 本项目中的例子 |
|---|---|---|
| Component | 数据字段 | AwardsComponent — 存 Total 和 LastLevelAwarded |
| System | 逻辑处理 / watcher | AwardGrantSystem — 响应通关事件,加奖励 |
| Entity | 多个 Component 的组合 | GameEntity — 一个实体可同时有 CurrentLevel + Awards + Lives 等 |
| Context | 全局状态仓库 / store | Contexts.sharedInstance.game — 所有 GameEntity 的容器 |
| Group | 筛选查询 / filter() | System 只处理"拥有特定 Component 组合"的 Entity 集合 |
| Matcher | 查询条件 / selector | Matcher<GameEntity>.Awards — 匹配所有有 Awards 组件的实体 |
能用自己的话说清 "Component 存数据,System 改数据,Entity 组合数据"。
ReactiveSystem = 事件驱动(类似 Vue watch),IExecuteSystem = 每帧轮询(类似 requestAnimationFrame)。
| 类型 | 基类 | 触发方式 | 前端类比 | 本项目例子 |
|---|---|---|---|---|
| ReactiveSystem | ReactiveSystem<GameEntity> |
关心的 Component 变化时自动触发 | Vue watch / useEffect deps | AwardGrantSystem、LivesMistakeSystem |
| IExecuteSystem | IExecuteSystem |
每帧执行 | requestAnimationFrame | InputSystem、TimerSystem |
按复杂度从低到高,每天一个模块。预计 5-7 天。
你之前已经改过这个模块,正好复习。它是理解"数据进 Component → System 改 → Savegame 存 → View 显示"这套完整模式的入口。
| 文件 | 看什么 | 路径 |
|---|---|---|
| AwardsComponents.cs | [Game, Unique] 标记含义、组件字段定义 | Assets/_Game/Awards/Components/ |
| AwardsFeature.cs | 怎么把系统聚合成 Feature | Assets/_Game/Awards/ |
| GameAwardsComponent.cs | 生成的代码:SetAwards / ReplaceAwards 是自动写的 | Assets/Generated/Game/Components/ |
| AwardGrantSystem.cs | ReactiveSystem 怎么响应 LevelComplete 事件 | Assets/_Game/Awards/Systems/ |
| AwardsSavegameSystem.cs | 运行时状态 ↔ 存档的双向同步 | Assets/_Game/Awards/Systems/ |
| AwardsSavegame.cs | partial class 扩展 GameSavegame 持久化字段 | Assets/_Game/Awards/Savegame/ |
| AwardToast.cs | View 怎么在 Update 里读 ECS 数据并弹出 | Assets/_Game/Awards/Views/ |
| AwardsCheatContainer.cs | 作弊容器:+1/+10/清零 | Assets/_Game/Awards/Cheats/ |
能说出从 LevelComplete 事件到奖励弹窗的完整数据流。
理解标志位组件(MistakeComponent / LevelFailedComponent)和 UI 动态渲染(心形图标)。
| 文件 | 看什么 | 路径 |
|---|---|---|
| LivesComponents.cs | MistakeComponent / LevelFailedComponent 标志位组件 | Assets/_Game/Lives/Components/ |
| LivesMistakeSystem.cs | ReactiveSystem 怎么响应 Mistake 事件 → 扣血 | Assets/_Game/Lives/Systems/ |
| LevelFailSystem.cs | 命值归零 → 触发 isLevelFailed | Assets/_Game/Lives/Systems/ |
| GameHud.cs | HUD 怎么动态创建心形图标 | Assets/_Game/Lives/Views/ |
| HeartView.cs | 单颗心的闪烁动画 | Assets/_Game/Lives/Views/ |
| LivesCheatContainer.cs | 命值作弊:满血/扣血 | Assets/_Game/Lives/Cheats/ |
能说出 "碰箭头 → Mistake → 扣血 → 0血 → LevelFailed → 弹窗" 链路。
理解关卡数据从 txt 文件到游戏场景的完整加载流程。
| 文件 | 看什么 | 路径 |
|---|---|---|
| LevelData.cs | 关卡数据类,怎么从 txt 读 | Assets/_Game/Levels/Data/ |
| LevelDifficultyUtil.cs | 难度工具类 | Assets/_Game/Levels/Data/ |
| GameStateComponents.cs | CurrentLevel / LevelComplete / LevelFailed 等状态组件 | Assets/_Game/Levels/Components/ |
| LevelStartSystem.cs | 加载关卡、创建箭头、创建点阵 | 查找 LevelStartSystem |
| LevelCompleteSystem.cs | 通关后的逻辑 | 查找 LevelCompleteSystem |
| LevelReloadSystem.cs | 重试/下一关 | 查找 LevelReloadSystem |
| LevelSavegameSystem.cs | 关卡进度存档映射 | 查找 LevelSavegameSystem |
| GridView.cs | 点阵的渲染 | Assets/_Game/Levels/Views/ |
Assets/_Game/Levels/Resources/Levels/level_1.txt,看看关卡数据文件长什么样。
能打开 level_1.txt 解释每一行数字的含义。
理解箭头之间的阻挡关系、点击判定、移动动画、通关判断。
| 文件 | 看什么 | 路径 |
|---|---|---|
| ArrowContainer.cs | 箭头的纯数据结构(方向、坐标、阻挡关系) | Assets/_Game/Arrows/Data/ |
| ArrowComponents.cs | 箭头的 ECS 组件 | Assets/_Game/Arrows/Components/ |
| ArrowPointerDownSystem.cs | 手指按下箭头的处理 | Assets/_Game/Arrows/Systems/ |
| ArrowClickSystem.cs | 核心:点击箭头的逻辑(拔出来 vs 撞到) | Assets/_Game/Arrows/Systems/ |
| ArrowTouchRemoveSystem.cs | 触摸移除箭头 | Assets/_Game/Arrows/Systems/ |
| ArrowBlockSystem.cs | 阻挡判定 | Assets/_Game/Arrows/Systems/ |
| ArrowMoveSystem.cs | 箭头的移动动画 | Assets/_Game/Arrows/Systems/ |
| ArrowsCompleteSystem.cs | 判断是否全部拔完 → 触发通关 | Assets/_Game/Arrows/Systems/ |
| ArrowView.cs | 箭头的渲染和动画 | Assets/_Game/Arrows/Views/ |
能解释 "点击箭头 → 判断是否可以拔出 → 不是,被挡住了 → 扣血" 这个逻辑。
理解输入如何从鼠标/触摸变成 ECS 事件,以及存档如何从 JSON ↔ GameSavegame ↔ 各业务子存档。
| 文件 | 看什么 | 路径 |
|---|---|---|
| InputSystem.cs | 鼠标/触摸 → PointerDown / PointerClick / Drag 事件 | Assets/_Game/Input/Systems/ |
| ArrowInputUtils.cs | 输入工具类 | Assets/_Game/Arrows/Systems/ |
| GameSavegame.cs | partial class 聚合存档的根 | Assets/GameBase/Savegame/ |
| SavegameComponents.cs | SavegameComponent / SavegameDirtyComponent | Assets/GameBase/Savegame/ |
| ISavegameService.cs | 存档服务接口 | Assets/GameBase/Savegame/ |
| JsonFileSavegameService.cs | JSON 文件落盘实现 | Assets/GameBase/Savegame/ |
| SavegameLoadSystem.cs | 启动时读文件 → Component | Assets/GameBase/Savegame/ |
| SavegameWriteSystem.cs | 有脏标记 → 写文件 | Assets/GameBase/Savegame/ |
| SavegameFeature.cs | 存档框架的 Feature | Assets/GameBase/Savegame/ |
能画出存档的读写流程图(JSON 文件 ↔ SavegameComponent ↔ 各业务子存档)。
把学到的东西写出来。预计 3-5 天。
模仿 Awards 模块,从头新建一个分数模块。这是检验你是否真正理解 ECS 模式的最佳方式。
[Game, Unique] 存 CurrentScoreLevelComplete,每次通关 +100 分partial class GameSavegame 加持久化字段通关后 HUD 上分数 +100,存档退出重进分数还在。
在 HomeScreenView.cs 里读 ECS 数据并渲染到 UI。练习 View 层的读数据模式。
contexts.game.awards.Total 并显示在主菜单上主菜单上能看到 "已获得 N 个奖励"。
深入理解代码生成、算法细节、测试框架。
| 内容 | 难度 | 说明 |
|---|---|---|
| 理解 Jenny 代码生成流程 | 中等 | 跑一次 Jenny.exe gen,理解哪些文件是生成的、哪些是手写的 |
| 看懂 ArrowContainer 算法 | 困难 | 箭头之间的 block 关系怎么算出来的 |
| 理解 CheatPanel 反射机制 | 中等 | 怎么自动发现所有 AbstractCheatContainer 子类 |
| 理解 SavegameSmokeTest | 中等 | 怎么用代码模拟一次完整的游戏流程并校验 |
| 理解 CheatSmokeTest | 简单 | 验证所有作弊项都能正常执行 |
| 理解 SmokeTest | 简单 | 通用冒烟测试框架 |
当你在 Components 文件里新增/修改了 [Game] 标记的组件后,需要重新生成代码。
Assets/Generated/ 下所有文件 — 自动生成,不要手改Assets/_Game/ 和 Assets/GameBase/ 下 — 手写代码
随时翻回来找文件。
| 目录 | 说明 |
|---|---|
Assets/GameBase/App/ | GameRoot / GameFeature / GameEnv |
Assets/GameBase/Ecs/ | GameAttribute([Game] 上下文属性) |
Assets/GameBase/Savegame/ | 存档框架(IO + 脏标记,不关心业务内容) |
Assets/GameBase/Cheats/ | 作弊框架(反射收集 + 面板渲染) |
Assets/GameBase/Destroy/ | 实体销毁 |
Assets/GameBase/Timer/ | 通用计时器 |
Assets/GameBase/Tools/ | 纯几何算法 |
Assets/GameBase/Ui/ | UGUI 构建助手 |
Assets/GameBase/Editor/ | 编辑器工具 |
Assets/_Game/Home/ | 主入口菜单 |
Assets/_Game/Arrows/ | 核心玩法:箭头 |
Assets/_Game/Levels/ | 关卡:加载/流程/点阵 |
Assets/_Game/Input/ | 输入:鼠标/触摸 → 指针事件 |
Assets/_Game/Lives/ | 命值:3 条命 / 撞击扣血 / 失败重来 |
Assets/_Game/Awards/ | 奖励:通关累计 + 弹窗提示 |
Assets/_Game/Hud/ | 游戏内 HUD |
Assets/_Game/Themes/ | 配色主题 |
Assets/_Game/Scenes/ | Home.unity / Main.unity |
Assets/Generated/ | Jenny 生成的 ECS 代码(不要手改) |
Assets/Entitas/ | Entitas ECS 运行时 |
Assets/Plugins/Demigiant/ | DOTween 补间动画 |
Jenny/ | 代码生成工具(Jenny.exe + 插件 dll) |
一些帮你少走弯路的经验。
[Unique] 标记的组件在整个 Context 里只有一份,通过 context.game.awards 直接访问。类比:全局唯一的 Vuex module。