# 白鹭客户端迁移 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。 - UI:uGUI,而不是 UI Toolkit。原因是现有项目是大量静态皮肤、图片、九宫格、按钮、弹窗、列表,uGUI 更容易还原白鹭 EUI 的层级和运行时行为。 - 文本:TextMeshPro。导入现有 `huakang.ttf`、`huakanghaibao.ttf`,检查授权后作为字体资源。 - 图集:Unity Sprite Atlas。由现有 `common.png/common.json` 等白鹭图集转换生成。 - 异步资源:Addressables。初期可以直接 Resources 跑通,但正式项目不建议长期依赖 Resources。 - 网络:UnityWebRequest 封装 HTTP,WebSocketSharp 或 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 版本有可对比基准。 ### 阶段 1:Unity 项目骨架 产出: - 新 Unity 项目。 - 目录结构。 - 启动场景。 - Canvas 640 x 1136。 - 日志、配置、事件总线、网络基础层。 验收: - 能在 Editor 启动并加载本地配置。 ### 阶段 2:资源导入工具 产出: - 白鹭图集导入工具。 - EXML 初版 prefab 转换工具。 - 字体导入和文本样式表。 - Addressables 分组。 验收: - 能自动生成登录页和一个普通弹窗的初版 prefab。 ### 阶段 3:登录闭环 产出: - 登录页。 - 注册/找回密码入口。 - `user/login` 对接。 - token 保存。 - 玩家基础数据 model。 验收: - Unity 能登录现有后端,并进入空主场景。 ### 阶段 4:主场景闭环 产出: - 主场景 UI。 - 顶部栏。 - 土地网格。 - 作物显示。 - 点击土地菜单。 - 获取农场数据。 验收: - 同一账号下,白鹭和 Unity 显示的土地、作物、资源一致。 ### 阶段 5:农场核心玩法 产出: - 种植。 - 收获。 - 除虫、除草、浇水。 - 施肥。 - 土地开放。 - 土地升级。 - 房屋升级。 验收: - 关键农场操作请求一致,服务端结果一致,UI 刷新一致。 ### 阶段 6:背包、仓库、商店 产出: - 背包面板。 - 仓库面板。 - 商店面板。 - 出售和购买。 - 道具使用。 验收: - 道具数量、金币钻石变化、错误提示与白鹭一致。 ### 阶段 7:外围系统 产出: - 好友。 - 消息。 - 日志。 - 公告。 - 签到。 - 抽奖。 - 礼包。 - 宠物。 - 加工合成。 - 兑换。 - 充值。 验收: - 每个系统至少有一条完整可回归流程。 ### 阶段 8:WebGL 或 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 体系承载。 短期优先把登录、配置、主场景、土地和顶部栏做成闭环。这个闭环跑通后,后续面板基本是重复的资源转换、接口绑定和状态刷新问题。