hy-farm/docs/unity-migration-rebuild.md
2026-05-29 19:54:56 +08:00

662 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 白鹭客户端迁移 Unity 重构文档
## 1. 目标
把现有白鹭 H5 农场客户端重建为一个新的 Unity 客户端,要求做到:
- UI 表现一致:布局、尺寸、层级、按钮状态、字体、弹窗动画、主场景比例尽量按现有白鹭版本复刻。
- 逻辑行为一致:登录、玩家数据、农场土地、作物状态、仓库、商店、好友、日志、充值、兑换、抽奖、签到、加工、宠物等流程与当前客户端一致。
- 后端协议一致:优先继续复用现有 Yii/PHP 接口和 Swoole socket 服务,不先重写服务端。
- 可维护性提升Unity 项目必须恢复清晰的模块边界,不能把白鹭压缩 JS 机械翻译成一坨 C#。
核心判断:这不是自动转换工程。当前仓库没有原始 TypeScript 源码、source map、`egretProperties.json`,不能从 `main.min.js` 完整还原白鹭工程。Unity 迁移应以现有资源、EXML、接口、数据库配置和运行表现为规格重新实现客户端。
## 2. 当前资产盘点
主要客户端路径:
- 白鹭部署目录:`muchang/home/web/game`
- 更完整的历史/发布资源目录:`muchang/farmer`
- 编译逻辑文件:`muchang/home/web/game/main.min.js`
- 另一份更大的编译逻辑文件:`muchang/farmer/js/main.min_77d7299f.js`
- UI 皮肤:`resource/skins/**/*.exml`
- 资源清单:`resource/default.res.json`
- 主题清单:`resource/default.thm.json`
- 配置数据:`resource/config/data.bin`
资源数量概览:
| 目录 | EXML | PNG | JSON | JPG | FNT | MP3 | TTF | BIN |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| `muchang/home/web/game/resource` | 102 | 289 | 21 | 7 | 5 | 2 | 2 | 1 |
| `muchang/farmer/resource` | 162 | 583 | 46 | 12 | 14 | 8 | 2 | 1 |
迁移时应以 `muchang/farmer/resource` 为优先素材源,因为它保留更多皮肤、图片、音频和配置。`muchang/home/web/game/resource` 用作线上当前版本对照。
## 3. 完全一致的定义
“完全一致”不能定义为源码一致,因为源工程已经缺失。应定义为下面三个层面的验收:
| 层面 | 验收方式 | 通过标准 |
| --- | --- | --- |
| UI 像素一致 | 白鹭版和 Unity 版在同一分辨率截图对比 | 主场景、登录、核心弹窗视觉差异可控,关键控件位置一致 |
| 交互一致 | 录制白鹭版操作路径Unity 重放 | 按钮响应、弹窗开关、动画方向、错误提示一致 |
| 协议一致 | Unity 请求现有后端接口 | 请求路径、参数、token、返回数据解析与白鹭一致 |
| 逻辑一致 | 对照 `main.min.js` 和后端 PHP 规则 | 种植、收获、升级、背包扣减、好友互动等结果一致 |
必须先建立白鹭版本的基准录像和截图,否则“完全一致”会变成主观判断。
## 4. Unity 技术选型
推荐选择:
- 渲染Unity 2D。
- UIuGUI而不是 UI Toolkit。原因是现有项目是大量静态皮肤、图片、九宫格、按钮、弹窗、列表uGUI 更容易还原白鹭 EUI 的层级和运行时行为。
- 文本TextMeshPro。导入现有 `huakang.ttf``huakanghaibao.ttf`,检查授权后作为字体资源。
- 图集Unity Sprite Atlas。由现有 `common.png/common.json` 等白鹭图集转换生成。
- 异步资源Addressables。初期可以直接 Resources 跑通,但正式项目不建议长期依赖 Resources。
- 网络UnityWebRequest 封装 HTTPWebSocketSharp 或 NativeWebSocket 封装 socket。
- 架构C# service + event bus + presenter不直接照搬 PureMVC。
设计分辨率:
- 白鹭当前入口是 `data-content-width=640``data-content-height=1136``data-scale-mode=fixedWidth`
- Unity Canvas Scaler 使用 `Scale With Screen Size`Reference Resolution 设置为 `640 x 1136`
- 所有 UI Prefab 先按 640 x 1136 复刻,再做安全区适配。
## 5. 新 Unity 项目结构
建议新建目录:
```text
unity/FarmUnity/
Assets/
FarmGame/
Art/
RawEgret/
Sprites/
Atlases/
Fonts/
Audio/
Config/
Raw/
Generated/
Runtime/
Bootstrap/
Core/
Network/
Data/
Services/
Farm/
Inventory/
Shop/
Friend/
Payment/
Socket/
UI/
Common/
Scenes/
Panels/
ItemRenderers/
Generated/
Editor/
EgretImport/
ExmlConvert/
AtlasConvert/
Tests/
EditMode/
PlayMode/
```
命名规则:
- 白鹭 `LoginSceneSkin.exml` 转为 Unity `LoginScene.prefab`
- 白鹭 `ShopSkin.exml` 转为 Unity `ShopPanel.prefab`
- 白鹭 `GameTopSkin.exml` 转为 Unity `GameTopView.prefab`
- 白鹭逻辑类 `GameTopLayer` 转为 `GameTopPresenter.cs`
- 白鹭通知 `PanelNotify.OPEN_SHOP` 转为 `UiEvent.OpenShop`
## 6. 白鹭到 Unity 映射
| 白鹭概念 | 当前表现 | Unity 迁移目标 |
| --- | --- | --- |
| `Main` | 启动、加载资源、主题、进入场景 | `GameBootstrapper` |
| `AppFacade/PureMVC` | 注册 command/mediator/proxy | `GameContext` + services + event bus |
| `PanelNotify` | UI 面板打开关闭事件 | `UiEvent` enum + `UiManager` |
| `SysNotify` | 系统刷新事件 | `GameEvent` enum + `EventBus` |
| `ClientNotify` | 农场行为命令 | `FarmCommand` |
| `BasePanel` | 弹窗基类、缩放动画、关闭按钮 | `PanelView` + `PanelPresenter` |
| `BaseMediator` | UI 与数据中介 | Presenter 或 Controller |
| `ResourceProxyBase` | 读取配置资源 | `ConfigService` |
| `Global.netProxy` | HTTP 请求封装 | `ApiClient` |
| `SocketCommand` | socket 消息映射 | `SocketMessageRouter` |
| `RES.getRes` | 资源加载 | Addressables/SpriteAtlas |
| `eui.Image` | 图片控件 | `Image` |
| `eui.Label` | 文本控件 | `TMP_Text` |
| `eui.Button` | 按钮 | `Button` + 状态图 |
| `eui.List` | 列表 | `ScrollRect` + item prefab pool |
| `egret.Tween` | 动画 | DOTween 或 Unity Tween 封装 |
## 7. UI 迁移策略
### 7.1 EXML 不能直接当 Unity UI 用
EXML 是白鹭 EUI 的 XML 皮肤描述Unity 不认识。正确路线是做一个导入器:
1. 解析 EXML 节点。
2.`e:Group` 转成 `RectTransform` 容器。
3.`e:Image` 转成 `Image`
4.`e:Label` 转成 `TMP_Text`
5.`e:Button` 转成 `Button` prefab。
6.`source` 映射到 SpriteAtlas 里的 Sprite。
7.`x/y/width/height/left/right/top/bottom/horizontalCenter/verticalCenter` 映射到 RectTransform。
8.`scale9Grid` 转成 sliced sprite。
9.`skinName``itemRendererSkinName` 转成嵌套 prefab 引用。
建议先做半自动转换:脚本生成初版 Prefab再人工校准关键页面。不要一开始追求 100% 自动化。
### 7.2 UI 优先级
第一批必须复刻:
- 登录:`LoginSceneSkin`
- 注册:`RegistSkin`
- 找回密码:`FindPasswordSkin`
- 主场景:`GameSceneSkin`
- 农场视图:`GameViewSkin`
- 顶部栏:`GameTopSkin`
- 主菜单:`MainMenuSkin`
- 左侧菜单:`LeftMenuSkin`
- 通用弹窗:`PanelCommonSkin``AlertSkin`
第二批:
- 背包:`BagPanelSkin``BagIconSkin`
- 仓库:`WareHouseSkin``WareHouseItemSkin``SellSkin`
- 商店:`ShopSkin``ShopItemSkin``ShopSkinItemSkin`
- 土地升级:`LandUpSkin``LandOpenSkin`
- 充值兑换:`PaySkin``ExGoldSkin`
- 日志/公告/帮助/设置/角色信息
第三批:
- 好友、赠送、聊天入口
- 签到、在线礼包、抽奖
- 加工、合成、兑换、宠物、皮肤
- 娱乐玩法和历史目录里额外资源
## 8. 资源转换策略
### 8.1 图集
白鹭图集通常由 `xxx.png` + `xxx.json` 组成。Unity 需要:
- 解析 JSON 里的 sprite 名、x、y、w、h、offset。
- 从 PNG 切 Sprite。
- 生成 SpriteAtlas。
- 保持 sprite name 与白鹭资源 key 一致,减少逻辑重写成本。
### 8.2 字体
现有字体:
- `resource/fonts/huakang.ttf`
- `resource/fonts/huakanghaibao.ttf`
- 若存在 `.fnt + .png`,转为 Unity bitmap font 或改用 TextMeshPro sprite asset。
风险:字体授权必须确认。未确认授权时只能内部迁移验证,不能直接上线。
### 8.3 配置
`resource/config/data.bin` 和后端 `GameConfigServices` 是关键。迁移时不要只看前端展示,还要确认服务端规则:
- `comm/game-config`
- `crop_list`
- `land_extend`
- `land_upgrade`
- `farm_level`
- `dog_level`
- `store_list`
- `item_list`
- `lottery`
- `player_level`
Unity 端应把配置解析成强类型 C# model并保留原始字段名避免接口对接时字段丢失。
## 9. 后端接口适配
Unity 客户端先复用现有接口。已从编译 JS 中识别出的核心接口如下:
```text
comm/broadcast
comm/clean-user-log
comm/game-config
comm/get-level-ranking
comm/get-notice-list
comm/get-user-log
comm/get-user-system-log
comm/lottery
comm/use-dog
compose/do
deal/deal
deal/deal-confirm
deal/get-list
factory/do
factory/upgrade
farm
farm/change-bg
farm/clear-land
farm/disease
farm/extend-land
farm/fertilize
farm/gather-crop
farm/sow-seeds
farm/upgrade
farm/upgrade-land
friend/add
friend/find
friend/friend-list
friend/get-respond-list
friend/respond
friend/respond-list
interaction/get-other-user-info
interaction/interaction
pay/pay
share
store-house
store-house/sell
store/buy
user/feed-dog
user/get-code-image
user/get-online-gift
user/get-rebate-list
user/get-wx-name
user/gold-exchange-gem
user/login
user/modify-password
user/modify-user-info
user/register
user/send-find-password-code
user/send-register-code
yutong_share
```
后端控制器入口包括:
```text
AchController.php
ArenaController.php
CommController.php
ComposeController.php
DealController.php
FactoryController.php
FarmController.php
FriendController.php
InteractionController.php
PayController.php
PetController.php
StoreController.php
StoreHouseController.php
UserController.php
```
Unity 网络层必须统一处理:
- base URL。
- token 注入。
- GET/POST 参数。
- JSON 反序列化。
- 错误码映射。
- 断线重连。
- 本地 mock 数据。
- 日志脱敏。
注意:当前白鹭本地调试出现过 `BigNumTostring undefined.toString`,说明本地 mock 或登录返回数据字段不完整。Unity 阶段必须建立接口契约,至少覆盖 `gold/gem/steel/stone/avatar/vip/level/exp/nickname` 等玩家字段。
## 10. 核心业务模块拆分
### 10.1 登录与账号
模块:
- `AuthService`
- `UserService`
- `SessionStore`
- `LoginScenePresenter`
- `RegisterPanelPresenter`
- `FindPasswordPanelPresenter`
流程:
1. 启动加载配置。
2. 检查本地 token。
3. 请求 `user/login` 或进入登录页。
4. 初始化玩家数据。
5. 请求 `comm/game-config`
6. 进入主场景。
### 10.2 主场景与农场
模块:
- `FarmService`
- `LandModel`
- `CropModel`
- `FarmScenePresenter`
- `GameViewPresenter`
- `LandView`
- `PlantView`
- `CoolMenuView`
必须复刻的行为:
- 12 块土地的坐标和透视排列。
- 土地开放、升级、种植、收获。
- 作物生长阶段。
- 干旱、虫害、杂草状态。
- 长按显示倒计时。
- 点击土地弹出操作菜单。
- 顶部资源刷新。
- 好友农场进入和返回。
### 10.3 物品、仓库、商店
模块:
- `InventoryService`
- `StoreHouseService`
- `ShopService`
- `ItemConfigService`
- `BagPanelPresenter`
- `WarehousePanelPresenter`
- `ShopPanelPresenter`
必须复刻:
- 道具类型和小类型。
- 道具数量变化。
- 出售、购买、使用。
- 皮肤道具切换。
- 消耗品校验和错误提示。
### 10.4 社交与消息
模块:
- `FriendService`
- `InteractionService`
- `SocketClient`
- `SocketMessageRouter`
- `FriendPanelPresenter`
- `FriendGivePanelPresenter`
- `MessagePanelPresenter`
必须复刻:
- 好友申请、响应、列表。
- 好友农场访问。
- 好友赠送。
- 系统跑马灯。
- socket 消息映射。
### 10.5 付费、兑换与活动
模块:
- `PaymentService`
- `ExchangeService`
- `LotteryService`
- `SignService`
- `OnlineGiftService`
注意:
- H5 微信支付和 Unity 支付链路不同。若目标是 Unity WebGL仍可通过 JS bridge 调用网页支付。若目标是移动 App需要重新设计支付 SDK。
- 支付相关逻辑必须以服务端为准Unity 只负责发起和展示。
## 11. 动画和交互还原
白鹭里大量使用 `egret.Tween`
- 弹窗打开:从中心缩放到 1。
- 弹窗关闭:缩放回中心并移除。
- 顶部栏滑入滑出。
- 按钮按下缩放到 0.9 后恢复。
- 跑马灯从右向左滚动。
- 收获飘字和资源变化提示。
Unity 应封装统一 `TweenService`
```text
TweenService.ScaleIn(panel, 0.25)
TweenService.ScaleOut(panel, 0.25)
TweenService.ButtonPress(button)
TweenService.Marquee(text, duration)
TweenService.FloatingTip(text, position)
```
不要在每个 Presenter 里散写动画细节,否则后期无法校准一致性。
## 12. 迁移实施阶段
### 阶段 0基准固化
产出:
- 白鹭版本可稳定运行。
- 10 到 20 条关键流程录像。
- 登录、主场景、弹窗、仓库、商店、种植收获截图。
- 接口请求和响应样本。
- 当前缺失字段和本地 mock 修复清单。
验收:
- 后续 Unity 版本有可对比基准。
### 阶段 1Unity 项目骨架
产出:
- 新 Unity 项目。
- 目录结构。
- 启动场景。
- Canvas 640 x 1136。
- 日志、配置、事件总线、网络基础层。
验收:
- 能在 Editor 启动并加载本地配置。
### 阶段 2资源导入工具
产出:
- 白鹭图集导入工具。
- EXML 初版 prefab 转换工具。
- 字体导入和文本样式表。
- Addressables 分组。
验收:
- 能自动生成登录页和一个普通弹窗的初版 prefab。
### 阶段 3登录闭环
产出:
- 登录页。
- 注册/找回密码入口。
- `user/login` 对接。
- token 保存。
- 玩家基础数据 model。
验收:
- Unity 能登录现有后端,并进入空主场景。
### 阶段 4主场景闭环
产出:
- 主场景 UI。
- 顶部栏。
- 土地网格。
- 作物显示。
- 点击土地菜单。
- 获取农场数据。
验收:
- 同一账号下,白鹭和 Unity 显示的土地、作物、资源一致。
### 阶段 5农场核心玩法
产出:
- 种植。
- 收获。
- 除虫、除草、浇水。
- 施肥。
- 土地开放。
- 土地升级。
- 房屋升级。
验收:
- 关键农场操作请求一致服务端结果一致UI 刷新一致。
### 阶段 6背包、仓库、商店
产出:
- 背包面板。
- 仓库面板。
- 商店面板。
- 出售和购买。
- 道具使用。
验收:
- 道具数量、金币钻石变化、错误提示与白鹭一致。
### 阶段 7外围系统
产出:
- 好友。
- 消息。
- 日志。
- 公告。
- 签到。
- 抽奖。
- 礼包。
- 宠物。
- 加工合成。
- 兑换。
- 充值。
验收:
- 每个系统至少有一条完整可回归流程。
### 阶段 8WebGL 或 App 发布适配
产出:
- WebGL 构建配置或移动端构建配置。
- JS bridge。
- 支付桥接。
- 微信环境能力替代方案。
- 资源热更新方案。
验收:
- 目标平台能登录、加载资源、完成核心玩法。
## 13. 测试策略
### 13.1 回归用例
必须覆盖:
- 登录成功、失败、token 过期。
- 初次进入农场。
- 种植并刷新。
- 收获并增加仓库物品。
- 土地升级扣材料。
- 购买商品扣货币。
- 出售仓库物品加货币。
- 好友列表和好友农场。
- 公告、日志、错误提示。
- socket 跑马灯。
### 13.2 对比测试
每个核心流程保存:
- 白鹭请求参数。
- 白鹭响应。
- 白鹭截图。
- Unity 请求参数。
- Unity 响应。
- Unity 截图。
只有当请求、响应和 UI 结果都一致,才算迁移完成。
## 14. 风险与处理
| 风险 | 影响 | 处理 |
| --- | --- | --- |
| 原始 TS 源码缺失 | 不能自动还原逻辑 | 以 `main.min.js` + 后端 PHP + 运行行为为规格重写 |
| EXML 自动转换不完整 | UI 还原成本高 | 半自动生成 prefab关键页面人工校准 |
| 白鹭和 Unity 坐标系不同 | UI 偏移、缩放异常 | 固定 640 x 1136 基准,建立坐标转换规则 |
| 图集切图错误 | 图片错位、九宫格异常 | 先做图集导入验证工具,对比 sprite rect |
| 后端接口字段不稳定 | 客户端运行时报错 | 建接口契约和本地 mock缺字段给默认值 |
| 支付和微信 JS 能力不可直接迁移 | 上线阻塞 | 提前确定目标平台,单独设计 bridge |
| 历史资源目录多版本混杂 | UI 和资源不匹配 | 以线上 `home/web/game` 为基准,`farmer` 只补素材 |
## 15. 开发规范
- C# 类名表达业务,不保留压缩 JS 里的短变量。
- Model 字段可以保留服务端原始 snake_case并提供 C# 属性包装。
- 所有接口必须走 `ApiClient`,禁止 UI 直接发请求。
- 所有 UI 打开关闭走 `UiManager`,禁止场景里随意 Instantiate。
- 所有事件走 `EventBus`,禁止跨模块直接引用 UI 实例。
- 每个面板拆成 View 和 Presenter。
- 每个接口建立 request/response 类型。
- 所有数值显示统一走 `NumberFormatter`,避免再次出现 `undefined.toString` 类问题。
## 16. 首批任务清单
1. 建立 Unity 空项目和目录结构。
2. 导入字体、音频、原始图片。
3. 写白鹭图集 JSON 解析器。
4. 写 EXML 到 prefab 的最小转换器。
5. 转换 `LoginSceneSkin`
6. 转换 `GameTopSkin`
7. 实现 `ApiClient``user/login`
8. 实现 `PlayerModel` 默认值保护。
9. 实现 `ConfigService``comm/game-config`
10. 实现主场景空壳和顶部栏资源展示。
11. 建立白鹭和 Unity 截图对比流程。
## 17. 交付物
最终交付应包括:
- Unity 工程源码。
- Egret 资源导入工具源码。
- EXML 转换工具源码。
- 接口契约文档。
- UI 页面映射表。
- 关键业务流程回归用例。
- 白鹭对比截图和 Unity 对比截图。
- 构建说明。
- 平台发布说明。
## 18. 结论
要保留 UI 和逻辑完全一致,正确路线是“重建客户端”,不是“反编译后改语言”。现有资源足够支撑 UI 高度还原,后端接口也能支撑逻辑复刻;最大成本在于把压缩 JS 中的业务流程重新结构化,并用 Unity 的 prefab、service、event bus、presenter 体系承载。
短期优先把登录、配置、主场景、土地和顶部栏做成闭环。这个闭环跑通后,后续面板基本是重复的资源转换、接口绑定和状态刷新问题。