18 KiB
白鹭客户端迁移 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 项目结构
建议新建目录:
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转为 UnityLoginScene.prefab。 - 白鹭
ShopSkin.exml转为 UnityShopPanel.prefab。 - 白鹭
GameTopSkin.exml转为 UnityGameTopView.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 不认识。正确路线是做一个导入器:
- 解析 EXML 节点。
- 把
e:Group转成RectTransform容器。 - 把
e:Image转成Image。 - 把
e:Label转成TMP_Text。 - 把
e:Button转成Buttonprefab。 - 把
source映射到 SpriteAtlas 里的 Sprite。 - 把
x/y/width/height/left/right/top/bottom/horizontalCenter/verticalCenter映射到 RectTransform。 - 把
scale9Grid转成 sliced sprite。 - 把
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.ttfresource/fonts/huakanghaibao.ttf- 若存在
.fnt + .png,转为 Unity bitmap font 或改用 TextMeshPro sprite asset。
风险:字体授权必须确认。未确认授权时只能内部迁移验证,不能直接上线。
8.3 配置
resource/config/data.bin 和后端 GameConfigServices 是关键。迁移时不要只看前端展示,还要确认服务端规则:
comm/game-configcrop_listland_extendland_upgradefarm_leveldog_levelstore_listitem_listlotteryplayer_level
Unity 端应把配置解析成强类型 C# model,并保留原始字段名,避免接口对接时字段丢失。
9. 后端接口适配
Unity 客户端先复用现有接口。已从编译 JS 中识别出的核心接口如下:
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
后端控制器入口包括:
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 登录与账号
模块:
AuthServiceUserServiceSessionStoreLoginScenePresenterRegisterPanelPresenterFindPasswordPanelPresenter
流程:
- 启动加载配置。
- 检查本地 token。
- 请求
user/login或进入登录页。 - 初始化玩家数据。
- 请求
comm/game-config。 - 进入主场景。
10.2 主场景与农场
模块:
FarmServiceLandModelCropModelFarmScenePresenterGameViewPresenterLandViewPlantViewCoolMenuView
必须复刻的行为:
- 12 块土地的坐标和透视排列。
- 土地开放、升级、种植、收获。
- 作物生长阶段。
- 干旱、虫害、杂草状态。
- 长按显示倒计时。
- 点击土地弹出操作菜单。
- 顶部资源刷新。
- 好友农场进入和返回。
10.3 物品、仓库、商店
模块:
InventoryServiceStoreHouseServiceShopServiceItemConfigServiceBagPanelPresenterWarehousePanelPresenterShopPanelPresenter
必须复刻:
- 道具类型和小类型。
- 道具数量变化。
- 出售、购买、使用。
- 皮肤道具切换。
- 消耗品校验和错误提示。
10.4 社交与消息
模块:
FriendServiceInteractionServiceSocketClientSocketMessageRouterFriendPanelPresenterFriendGivePanelPresenterMessagePanelPresenter
必须复刻:
- 好友申请、响应、列表。
- 好友农场访问。
- 好友赠送。
- 系统跑马灯。
- socket 消息映射。
10.5 付费、兑换与活动
模块:
PaymentServiceExchangeServiceLotteryServiceSignServiceOnlineGiftService
注意:
- H5 微信支付和 Unity 支付链路不同。若目标是 Unity WebGL,仍可通过 JS bridge 调用网页支付。若目标是移动 App,需要重新设计支付 SDK。
- 支付相关逻辑必须以服务端为准,Unity 只负责发起和展示。
11. 动画和交互还原
白鹭里大量使用 egret.Tween:
- 弹窗打开:从中心缩放到 1。
- 弹窗关闭:缩放回中心并移除。
- 顶部栏滑入滑出。
- 按钮按下缩放到 0.9 后恢复。
- 跑马灯从右向左滚动。
- 收获飘字和资源变化提示。
Unity 应封装统一 TweenService:
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. 首批任务清单
- 建立 Unity 空项目和目录结构。
- 导入字体、音频、原始图片。
- 写白鹭图集 JSON 解析器。
- 写 EXML 到 prefab 的最小转换器。
- 转换
LoginSceneSkin。 - 转换
GameTopSkin。 - 实现
ApiClient和user/login。 - 实现
PlayerModel默认值保护。 - 实现
ConfigService和comm/game-config。 - 实现主场景空壳和顶部栏资源展示。
- 建立白鹭和 Unity 截图对比流程。
17. 交付物
最终交付应包括:
- Unity 工程源码。
- Egret 资源导入工具源码。
- EXML 转换工具源码。
- 接口契约文档。
- UI 页面映射表。
- 关键业务流程回归用例。
- 白鹭对比截图和 Unity 对比截图。
- 构建说明。
- 平台发布说明。
18. 结论
要保留 UI 和逻辑完全一致,正确路线是“重建客户端”,不是“反编译后改语言”。现有资源足够支撑 UI 高度还原,后端接口也能支撑逻辑复刻;最大成本在于把压缩 JS 中的业务流程重新结构化,并用 Unity 的 prefab、service、event bus、presenter 体系承载。
短期优先把登录、配置、主场景、土地和顶部栏做成闭环。这个闭环跑通后,后续面板基本是重复的资源转换、接口绑定和状态刷新问题。