源码学习仓库同步记录(2026-09-23):已从可运行的完整工程补入微信小游戏转换器、YooAsset、HybridCLR/WebGL 及旧启动链所需代码依赖;导出目录改为仓库内的
wx-export/,平台 AppID/CDN 保持占位值。补齐依赖后按负责人要求不再做仓库副本的编译或导出验证。该仓库仍缺原游戏部分旧美术,不能据此宣称独立出包已验证。操作边界见README.md。
上一版快照(2026-09-20 的四步结构性收敛)已完成,过程见本文件历史轮次(第 1~90 轮)。以下是当前状态。
负责人 2026-09-22 宣布:「全部界面的 UI 验收算通过了」,剩余的排行榜等页面由负责人自行调整。 ⇒ UI 适配主线收口,我方停止代改;当前转入"记录 + 护栏 + 可回归校验"状态。下方 §已收口 是本阶段结论。
表驱动(10 表/49 英雄) · ProfilePage 收口 · BUG-018 玩家名/ID/战力 · BUG-019 部分(品质+立绘表) · BUG-020 购买进度条 ·
BUG-023② 道具类型语义 · BUG-026 六项(遮罩/红点/提示/底栏/阵容卡/阵容关闭) · BUG-027 三项(客服关闭/邮箱全部删除/排行榜 50 名) ·
滚动列表根因修复(撑高+Clamped+顶部对齐,10 页接入) · 大厅窄高比适配(负责人已确认"大厅好了") · BUG-025 方案 C(ClientBoot 置首,构建顺序 ClientBoot → Boot → ClientShell) ·
冗余阵容卡清理 · 改名链路死按钮修复 · 个性化交互(选中→确定键替换)+ 演示数据(ClientShow 全开) · 英雄详情等 6 页接入滚动修复 · Pending shipmentCanvas 底栏铺满 ·
⭐ UI 适配 第 1+2 批(2026-09-22 负责人复验通过:"修好了"):英雄详情三个技能页签的文字贴图/选中框切换、后退键、等级卡位置、英雄页卡牌列表几何
验证三件套:Logs/verify-compile.ps1(三目标 0 error)· ClientSelfTest(96 项 / 失败 0)· 审计脚本 ui-contract-audit / ui-type-audit / ui-flow-matrix / ui-dead-buttons / ui-layout-audit / ui-adapt-audit{,2}
负责人决定:排行榜等剩余页面自己调,且「全部界面的 UI 验收算通过了」。 我方停止代改,转为记录 + 护栏。
完整执行记录见 UI_ADAPT_BACKLOG.md;定稿锚点规则与"已手调值"见 UI_ANCHOR_SIGNOFF.md(§三之二、§三之三)。
已交付并通过验证的部分(可回归):
- 第 1+2 批:英雄详情 3 个技能页签的选中态皮肤(贴图+底框切换)、后退键、等级卡、英雄页两份卡牌列表几何
—— 负责人亲验"修好了";
ui-adapt-audit3PASS 37/0、selftest-scene-mirrorPASS 35/0。 - 第 4 批 #6 排行榜(列表几何部分):战力榜 Viewport 曾塌成 0×0 ⇒
RectMask2D失效、内容画到框外; 两份 Content 中锚 + pivot(0,1) 被横向推出;网格对齐 MiddleCenter。均已修(FixRankPageLists()+ 菜单 8 + 文本补丁)。 - 新增只读校验(可随时跑,不会改场景):
Logs/rank-resolve-check.ps1—— 4 条列表几何断言 + 6 条"是否随画布高度漂移"断言Logs/rank-layout-check.ps1—— 全场景 16 份竖向列表的布局级体检(视口必须有真实面积 / 内容不得宽于视口)Logs/verify-adapt12-offline.ps1—— 一条命令跑 8 项(编译/审计/自检镜像/引用校验/补丁安全/排行榜/布局/完整性)
已知未闭环项(如实记录,不是"已完成"):
RankPage排行榜里 6 个节点仍是中锚(Challange/Ballte Mall、Explanation text frame、两份tips、两个榜单容器) ⇒ 在 1080×1920(画布高 1339 vs 设计 1630)下会整体下移 145.5 单位,即负责人反馈的"标题出框 / 说明框与未上榜位置不对"。 修复已实现并编译通过(FixRankPageStableAnchors(),按 1630 基准回写等效 offset,设计比例下位置不变), 但未写入场景 —— 负责人选择自行调整。- 两个 Viewport 的
sizeDelta疑似互换:战力榜(-17,0)、挑战榜(0,0)(原属挑战榜的值跑到了战力榜)。 战力榜已不塌陷故不会出框,仅右边窄 17 单位。已记入UI_ANCHOR_SIGNOFF.md§三之三 供负责人核对。 - 全场景布局体检仅剩 1 项不合格:
ShopPage商店/Product page/展示卡牌Scroll View(视口宽 678.2 < 内容宽 704.9 ⇒ 左右被裁), 对应 backlog #5 商店;#7 邮箱有同源疑点。负责人已宣布验收通过,故未实施。
护栏(防止我这边把负责人的手调拽回去):
Logs/apply-rank-text.ps1默认拒绝写入(exit 5),需显式-OwnerApproved;-DryRun仍只读可用。Logs/apply-adapt12-text.ps1检测到编辑器在跑就拒绝写入(exit 3),且不加-ForceLayout不碰任何位置值。- 编辑器工具
FixRankPageStableAnchors()只改"还是中锚"的节点;已是贴顶锚的一律跳过。 - 审计脚本只断言锚点类型 / 是否贴边,不再断言具体 offset(避免把手调判成失败)。
- 编辑器可能在跑旧编译产物:菜单项存在但方法体是上一版 ⇒ 表现成"点了只改一半"。
判别:比对
Library/ScriptAssemblies/Assembly-CSharp-Editor.dll与源码时间戳,或直接在 DLL 原始字节里搜 你新写的日志字面量。verify-compile.ps1绿 ≠ 编辑器 DLL 是新的(它是独立 Roslyn 编译)。 可靠解法:点回 Unity 窗口 /Ctrl+R等编译完成,或关掉编辑器用批处理-executeMethod。 另:别在菜单方法里调AssetDatabase.Refresh()—— 会触发域重载把正在执行的方法打断。 - 节点名可以字面含斜杠:
Challange/Ballte Mall是一个 GameObject 的名字,不是两级路径 ⇒Transform.Find("Challange/Ballte Mall")永远找不到。要用"遍历直接子节点按名字片段匹配"。 见UI_ADAPT_BACKLOG.md(含分批表与完整执行记录)。
第 1+2 批:✅ 已验收通过(负责人 2026-09-22 亲验:"修好了")。 验证证据:三目标编译 0 error · 静态审计 PASS 37/0 · 自检断言静态镜像 PASS 35/0 · 场景完整性 OK · 文本补丁幂等; 且补丁经历了 Unity 自己的保存往返(09:27 保存后 37/0 依旧成立)⇒ 手写 YAML 补丁被证明有效。
第 4 批 #6(排行榜):✅ 已修复并验证(2026-09-22)。
-
真根因(实读,非估算):排行榜页里放了两份位置完全相同的列表容器(
Challenge List挑战榜 /Battle Power Ranking战力榜),由底部两个按钮切换显隐。两份配置不一致:- 战力榜
Viewport锚点(0,0)-(0,0)+sizeDelta (0,0)⇒ 视口塌成 0×0,它的RectMask2D什么都裁不住 ⇒ 内容按自家位置画到框外 = 负责人说的"两个 ranking 穿过下方 UI 底框"; 挑战榜那份虽是(0,0)-(1,1)但sizeDelta.x = −17(同样不对)。 - 两份
Content都是中锚 + offset x ≈ 376 而 pivot 是(0,1)⇒ 配合运行时贴顶后横向被推出去 = "上方 UI 错位";且GridLayoutGroup.childAlignment还是MiddleCenter(4)(应为UpperLeft)。
- 战力榜
-
修法:
ClientShellStructuralRepair.FixRankPageLists()+ 菜单8. 排行榜列表修复: Viewport 贴满 Scroll View、Content 改左上锚 + offset 归零、网格对齐 UpperLeft。不动尺寸/行高/底栏。 -
验证:
Logs/rank-resolve-check.ps1→ RANK CHECK: OK;ui-adapt-audit3PASS 37/0;selftest-scene-mirrorPASS 35/0;三目标编译 0 error。 -
⚠️ 本轮最耗时的坑(已记入UI_LAYOUT_DEBUG_GUIDE.md§7):那个编辑器进程始终没重新编译, 点菜单 8 多次都只跑了旧代码(Content 变了、Viewport 没变)。最终用 批处理(Logs/repair-rank-batch.ps1,必定从源码全新编译)+ 文本补丁(Logs/apply-rank-text.ps1补唯一漏项) 两条互补手段落地。另:判断"工具到底改没改"要重新解析文件内容,不能只看 mtime。 -
同源线索(下批用):
Logs/rank-layout-check.ps1新增全场景 16 份竖向列表的布局级体检 (视口必须有真实面积 + 内容不得宽于视口),现只剩 1 份不合格:ShopPage商店/Product page/展示卡牌Scroll View(视口宽 678.2 < 内容宽 704.9 ⇒ 左右被裁)—— 正是 backlog #5 商店「道具卡牌的 Content 有问题」,病根已定位。 -
第 1 批(P0 回归)· 英雄详情 3 个技能页签 —— 真根因(三层): ① 层级是
Toggle/Background/Checkmark(Checkmark 是 Background 的子节点); ②技能区/{天赋,秘技,终结技}选中框.png全工程零引用; ③ 三个底框贴图接错(天赋挂秘技的、秘技挂天赋的且m_Enabled: 0)。 修法:ClientHeroDetailToggleSkin按选中段换底框 sprite + 文字恒显;工具写入贴图与绑定;ClientSelfTest防回归断言。 -
第 2 批:①
后退Button改左上锚(中锚在 1339 画布落到y=-35~26);②leftmiddleCanvas贴 downCanvas 顶部 (原中锚y=730~957与upCanvas/right重叠)+ 属性条联动下移;③ 英雄页两份卡牌Content改左上锚 (原 offset(-299,503)⇒ 整列跑到滚动框左外、压住『弹珠』)。负责人复验后又自己微调了这三处的 offset, 已记录进UI_ANCHOR_SIGNOFF.md§三之二(勿被工具回退)。 -
负责人下一步(2 步):① 先让编辑器重新导入(点一下 Unity 窗口 /
Ctrl+R)—— 本轮实测那个进程的Library/ScriptAssemblies/Assembly-CSharp.dll停在 17:43、Assembly-CSharp.csproj不含新脚本,即内存里还没有这个类型; 导入成功后再进 Play 复验(若仍报缺失脚本,点菜单Client → 结构修复 → 7. UI 适配 第 1+2 批即可修好); ② 要跑编辑器内自检时先关编辑器,再跑powershell -NoProfile -ExecutionPolicy Bypass -File Logs\verify-adapt12.ps1。 -
不打开 Unity 也能跑的三道校验(全绿):
Logs/ui-adapt-audit3.ps1(PASS 37/0)·Logs/selftest-scene-mirror.ps1(ClientSelfTest场景断言的静态镜像,PASS 35/0)·Logs/check-handoff-refs.ps1(皮肤组件每个引用都指向真实对象/资源,OK)。 -
静态审计:
Logs/ui-adapt-audit3.ps1(只读,退出码可判定)。修复前 PASS 26 / FAIL 11 ⇒ 修复后 PASS 37 / FAIL 0。 -
自检镜像:
Logs/selftest-scene-mirror.ps1(只读)=ClientSelfTest场景断言的静态等价物,PASS 35 / FAIL 0; 编辑器内的ClientSelfTest仍需关掉编辑器后跑(Logs/verify-adapt12.ps1)。 -
⚠️ 教训(已记入UI_LAYOUT_DEBUG_GUIDE.md§7):审计脚本不要硬编码 transform fileID —— 本轮第一版把两份卡牌Content的 id 写错(268087959其实是图鉴页),于是英雄页那份漏改; 改用"按真实层级走路径"后才暴露。路径式查找才是可靠做法(C# 工具一直用路径式,所以一直是对的)。 -
场景写入方式(重要):编辑器当时占着工程、批处理起不来,因此本轮用
Logs/apply-adapt12-text.ps1把与编辑器工具完全相同的值写进场景 YAML,并用"写入后重新解析 + 逐条断言贴图/锚点 +Logs/check-scene-integrity.ps1对比 document 集合"三重护栏保证没写坏;编辑器工具仍是权威路径且幂等。
ClientCanvas 参考 753×1630 + matchWidthOrHeight = 0(按宽)⇒ 宽恒 753、高 = 753×(H/W):
1080×2280→1590 · 1080×2160→1506 · 1080×1920→1339。
⇒ 横向稳定,纵向全靠贴顶/贴底/拉伸;凡"固定高度或固定纵向位置"的内容在矮画布上必然溢出/被裁/重叠。
UI_ADAPT_BACKLOG.md—— 11 项反馈 + 分批计划 + 第 1+2 批的完整执行记录(真根因/修法/验证状态)UI_LAYOUT_DEBUG_GUIDE.md—— 五步排查法 + 现象→锚点嫌疑对照表 + 踩坑清单UI_ANCHOR_SIGNOFF.md—— 已定稿的锚点规则 + 4 条微调注意事项BUG_TRACKER.md(BUG-025~BUG-027)·Assets/Client/MODULE.md§18(审计方法)·Assets/Client/UI/HeroDetailPage/MODULE.md(技能页签真实层级)- 移植侧:
WEBGL_B0_GATE.md/WEBGL_B1_BUILD.md/WEBGL_B2_DIAGNOSTICS.md/HANDOVER_PLAN.md
- 跑批处理 Unity 必须先关掉编辑器(否则
HandleProjectAlreadyOpenInAnotherInstance崩溃,退出码0x40000015);子进程临时传ALLUSERSPROFILE=C:\ProgramData - 场景节点路径必须带完整前缀
ClientCanvas/PopupLayer/...;中文名在 YAML 里是\uXXXX转义(比对前反转义);prefab 实例内部节点静态扫不到;GameObject.Find找不到未激活对象 .ps1里不要写中文字面量(PowerShell 按 ANSI 读会乱码 ⇒ 用字符码或从文件读); 另注意$ID是 PowerShell 内置只读变量(用$NODEID),且$arr = @($a + 'x', $b + 'y')会因逗号优先级被当成一个元素 ⇒ 每个元素要各自加括号- 场景改动前先备份到
Logs/ClientShell.before-*.unity.bak;修正要写进幂等的编辑器工具,负责人可点Client → 结构修复 → 2. 执行结构修复自行应用 Logs/下的脚本、日志与*.unity.bak都是证据,不要删
旧决定
D1 = 不动入口(Init.cs不改、ClientShell不进 Build Settings)已被 2026-09-22 的实际工作推翻, 但负责人【未】给出长期授权。 📌 授权状态(负责人 2026-09-22 明确口径):本会话对Init.cs/Boot.unity/ 构建清单 /MiniGameConfig.asset的改动是【经负责人逐次口头许可】进行的;后续任何改动仍需【逐次确认】,不得视为已获长期授权。 ⇒ 新会话若要再动这些文件(含Init.cs的场景加载改动),必须先向负责人确认。 可自由改动、无需单独确认的:Logs/下的脚本与文档、纯 Markdown 文档。
目标 状态 关键证据 可构建 ✅ 一条命令 8 分钟出包, WXConvertCore.DoExport返回SUCCEED可启动 ✅ 微信开发者工具里进入客户端界面 可操作 ✅ 负责人确认「各界面跳转和功能没问题」 真实会话(TCP) ✅ 网关成功 → TCP建连成功 → 握手成功 → 游客登录成功 → 英雄数据接收并解析成功:英雄=4,英雄组=1 → 成功退出 TCP真机 ⬜ 未做 首页修复后再推( HANDOVER_PLAN.md§5 B2 矩阵)根因:
ClientShell不在 YooAsset 寻址清单里 (收集器只收Assets/HotUpdateResources/*,没有Assets/Client/*), 而Init.cs:192用YooAssets.LoadSceneAsync(名字)按地址加载 ⇒Failed to mapping location to asset path : ClientShell⇒ 场景没加载。 与BUG-025同源("场景在清单外"),只是这次场景在 Build Settings 里、却不在 YooAsset 清单里。复验证据(负责人导出的微信开发者工具 Console,13,647 行,只读副本本会话已核对):
加载Init→首个场景:ClientShell→首个场景加载方式判定:构建清单场景数=2,目标=ClientShell(L2875) → 全文件 0 处Failed to mapping location to asset path/Failed to load scene(对照修复前) →[配置表] … Hero 可用 49 / 表内 54(L3212)= 客户端组合根已运行 →[ClientProfileNavigationController] ActiveVisualCanvases:count=7,paths=ClientCanvas | ClientCanvas/PagesLayer/MainPage主页/…(L12578)= 首页 UI 已激活 →资源包初始化成功+Updated package Version : 2026-09-22-1420(L2494)= YooAsset 走根目录正常 → TCP 六包齐全(网关成功 → TCP建连成功 → 握手成功 → 游客登录成功 → 英雄数据 英雄=4/英雄组=1 → 成功退出) → 无异常、无缺失脚本;运行 84s,卡顿率 3.6%
- 完整根因 + 两个修复方案对比 →
HOME_PAGE_SCENE_FIX_OPTIONS.md- 面向非技术同事的解释版 →
D:\Users\Administrator\Desktop\notd\首页不显示-根因说明.md- TCP 断链的完整分析(已修复,含证据链)→
TCP_NETWORK_BREAK_ROOTCAUSE.md✅ 负责人 2026-09-22 已选定并授权:方案 A(改用
SceneManager.LoadSceneAsync加载ClientShell)。 ✅ 2026-09-22 晚已实施完成(唯一文件Assets/Main/Init.cs,备份Logs/Init.cs.before-planA.bak): 新增LoadFirstSceneAsync(),两处调用点(运行时原 L192 +OnCompleted()原 L518/编辑器分支)都接入, 内置场景起不来时回落YooAssets.LoadSceneAsync(原行为逐字保留)。⚠️ 交接文档原先只提到 L192,漏了 L518 —— 不改编辑器分支,编辑器里 PlayBoot仍进不去首页。 详细记录与本次 OSS 重传清单 →HOME_PAGE_SCENE_FIX_OPTIONS.md§九 ·Logs/webgl-port/OSS_UPLOAD_MANIFEST-planA.txt✅ 已复验通过(2026-09-22 晚):容器内场景加载成功且首页 UI 已激活(证据见本条上方); 负责人已确认「首页肉眼可见」;OSS 上两个新首包文件(124561790dc5891e…data…br/f646dc49cc019398…wasm…br)实测均 200。⚠️ 新发现(已取证,是否修待决策):方案 A 里预留的首个场景已加载(SceneManager 内置场景)日志没有打印 (全文件 0 匹配)⇒Init协程在LoadSceneMode.Single切场景时随Boot场景一起被销毁,Init.cs中"加载后"那段(ApplyWebGLRenderCompatibilityToLoadedCameras()+WebGLFirstScreenDiagnosticsHost)不会执行 (日志中WebGLFirstScreen同样 0 匹配)。这是既有设计问题、非方案 A 引入,实测渲染正常; 要修需再次动Init.cs(按授权口径须负责人逐次确认)。 ✅ A4 已获授权并已实施(2026-09-22 晚):新增Assets/Main/WebGLPostSceneLoadRunner.cs(跨场景宿主,不声明任何[SerializeField],避免字段布局不一致导致构建失败),Init.cs把"加载后"两个动作(相机兼容处理 + 首屏诊断)改为由它在SceneManager.sceneLoaded时执行一次;Init自身生命周期未改(探针仍依赖"Boot 场景会被卸载"这一前提)。 已编译 0 error、已出包 exit=0;构建标识DATA_FILE_MD5=356e1b81e1be0bb4、CODE_FILE_MD5=2edcf1b6d32ca4ab。 重传清单 →Logs/webgl-port/OSS_UPLOAD_MANIFEST-A4.txt;真机手册 →WEBGL_B2_REALDEVICE.md。 ✅ 已容器复验通过(2026-09-22 晚,负责人 Console 截图):首个场景已加载(sceneLoaded 事件):ClientShell,模式=Single;由跨场景宿主执行加载后处理。
WebGL 渲染兼容性已应用:Client UI Clear Camera/WebGL 渲染兼容性已注册:已检查 1 台相机;后续相机将在 URP 渲染前处理。[WebGL 首屏诊断 1s] scene=ClientShell, loaded=True, resolution=1170x2532, cameras=1, canvases=72, pipeline=Universal Render Pipeline Asset, skybox=Default-Skybox, reflection=none[WebGL 首屏相机 1s] … hdr=False, post=False(说明兼容处理确实生效)。 ⬜ 待留意:本次 Console 计数为 1 error / 20~21 warnings;10s那条诊断未在截图范围内。 已知非致命项(404 版本探测 / ETC 纹理回退 / 开发阶段上报提示)见WEBGL_B2_REALDEVICE.md§五,未取证的 error 不当成已知项。
文件 改动 目的 Assets/Client/Runtime/ClientTcpConnectionProbe.cs9 个 [SerializeField]移出#if UNITY_WEBGL修构建级根因:字段集在编辑器/播放器不一致 ⇒ script class layout is incompatibleProjectSettings/EditorBuildSettings.asset清单改为 Boot(0) → ClientShell(1)(移除ClientBoot)回归历史启动链,让 Boot/Init能加载 HotFixAssets/Main/Boot.unityClientStartScene: ClientShell;Default/FallbackHostServer→ 新 CDN首个场景指向客户端 Assets/Main/Init.cs新增 ClientStartScene字段 +ResolveFirstSceneName()(默认空 = 原行为LoginScene)可配置加载目标,不破坏原逻辑 Assets/WX-WASM-SDK-V2/Editor/MiniGameConfig.assetCDN→.../WebGL/pinball-client换到干净 CDN 目录 Assets/Client/Runtime/ClientBootLoader.cs移除探针挂载 + 标注弃用 它已不在启动链 Assets/Client/Editor/ClientWebGLBuildCommand.cs新增:命令行构建 6 步管线 + 启动链校验 一键出包 Assets/Client/Editor/ClientSelfTest.cs拆出 RunAllCore()(不结束进程)供管线内调用
文件 用途 run-pipeline-2phase.ps1一键出包: pwsh -File ... -PackageVersion <版本>(两阶段,约 8 分钟)upload-to-oss.ps1ossutil 上传(含上传后自检); -DryRun可只看命令OSS_UPLOAD_MANIFEST.txt上传清单,含路径、逐项文件名、自检 URL (
wx-auto/自动化探针目录已于 2026-09-22 清理删除,连同 2 个被取代的旧脚本与 17 个空日志;见第 3 条坑。)
ClientTcpConnectionProbe的[SerializeField]不能放在#if UNITY_WEBGL内。 否则编辑器侧与播放器侧字段布局不一致,Unity 直接拒绝构建:Error building player because script class layout is incompatible between the editor and the player.字段本身不依赖 WebGL 类型,声明放外面;只把用它们的逻辑放进#if。- YooAsset 的资源放在 CDN【根目录】,不是
/Assets/。Init.cs:476-482→GetRemoteMainURL(fileName) => $"{host}/{fileName}", 而host = .../WebGL/pinball-client(根)。 那个/Assets层级是微信 SDK 首包(webgl.data/wasm/ 纹理)用的,与 YooAsset 无关。 → 同一类路径错配本会话踩了两次(先少一层、后多一层,即BUG-015与本次)。 教训:上传后必须按客户端实际请求的 URL 逐个自检,不能靠推断。- 不要试图用
miniprogram-automator读小游戏的 Console。 实测:cli auto --auto-port <port>能握手成功,但evaluate/systemInfo/currentPage全部超时, 且小游戏没有getConsoleMessagesAPI。已验证为死路,不要再花时间。 (过程产物Logs/webgl-port/wx-auto/已删除,勿重建。另外:用cli auto时不要连带 kill 父进程, 会杀掉开发者工具主进程 —— 本会话踩过。)- 微信开发者工具的服务端口开关:设置 → 安全设置 → 服务端口。开着
cli才能用。 但即使开着,对小游戏也只能握手、不能查数据。- 改 CDN 目录必须同时改两处:
MiniGameConfig.asset的CDN与Boot.unity的DefaultHostServer/FallbackHostServer。改完必须重跑转换(game.js里写死了DATA_CDN)。- 只调 UI 时,重跑构建后通常只需重传
data.br一个新文件: 实测连续多次构建wasm.br哈希不变(未改 C# 时);改了构建清单或代码wasm.br才会变。edit工具会剥掉 UTF-8 BOM(CRLF 保留)。改 BOM 文件后要复查并手工补回。- 本机一律用
pwsh(PowerShell 7);5.1 会把无 BOM 的 UTF-8 脚本当 ANSI 读,含中文直接解析失败。
- 读本节 +
HOME_PAGE_SCENE_FIX_OPTIONS.md§九(方案 A 已实施,并在容器内复验通过);- ✅ 首页阻塞已解除:新
data.br/wasm.br已上传 OSS 并实测 200,容器 Console 证据见本节;- ✅ 真机已通过(2026-09-22):Android 1080×2400 真机、A4 构建(
DATA_FILE_MD5=356e1b81e1be0bb4)。 未开调试被downloadFile:fail url not in domain list拦下;开「调试」后资源下载通过 → 首页正常渲染、编队页/新手任务页可跳转、TCP 六包在真机全部走完(英雄=4,英雄组=1)、RT-FPS 50~63 / Jank 0 / Stutter 0.00%、无致命异常。 ⇒ 阶段 B 五项(可构建/可启动/可操作/真实会话/真机)全部达成;实测记录见WEBGL_B2_REALDEVICE.md§八。- ⬜ 剩余:B2 矩阵深度项(安全区与遮挡、返回栈压测、弱网/断网、后台切回、内存峰值未采集); 以及生产化前置——正式版/体验版必须配合法域名,而裸 IP 的发现服务与网关无法加白,需服务端侧提供 HTTPS 域名(属服务端范围)。
- 📖 移植侧总入口(阶段 C):
WEBGL_MINIGAME_HANDBOOK.md(环境事实 / 一键出包 / 上传规则 / 容器与真机取证 / 排查表 / 坑清单 / 授权边界); 模块级 →Assets/Main/MODULE.md;缺陷与风险 →BUG_TRACKER.md(BUG-025已闭环、新增BUG-028与RISK-021); 阶段状态与决策 →DEVELOPMENT_WORKFLOW.md「2026-09-22 移植阶段状态与决策记录」。- ⬜ 待决策(需授权动
Init.cs):是否修「Init被Single模式销毁 ⇒ 加载后诊断/相机兼容处理不执行」;- ⬜ 待确认:UI 后续是否还会频繁调整(决定是否值得上方案 B,换回 UI 热更能力)。
📌 2026-09-20 只读基线仍有效:
WEBGL_PORT_BASELINE.md(工作区差异 / 启动链实测 / 编译验证 / TCP 日志证据 / 资源与 OSS 实测 / 风险主次)。 该文件是只读盘点产物,其余内容(UI 收敛进度)由原会话维护,两者不冲突。 三条否定性事实仍然成立,但第 ① 条已被本会话消除: ①→ 已解决(已进 Build Settings,ClientShell没有任何运行时入口Init.ClientStartScene指向它;仅剩 YooAsset 寻址问题); ②GameController.StartWebGLLobbyPreview是死代码(全工程零调用方); ③ WebGL 热更HotFix.dll.bytes曾落后——已在本会话重新生成并纳入管线。
按序读这六份:AGENTS.md(§4 是 WebGL/黑屏的取证纪律)→ HANDOVER_PLAN.md(A/B/C 三阶段总纲 + 三层架构目标)→ TCP_WEBGL_HANDOFF.md(TCP 那条路的权威记录) → TCP_NETWORK_BREAK_ROOTCAUSE.md(TCP 断链的完整分析与修复) → HOME_PAGE_SCENE_FIX_OPTIONS.md(首页阻塞:根因 / 方案对比 / §九 实施与复验,已闭环) → WEBGL_MINIGAME_HANDBOOK.md(移植侧总入口) → Assets/Client/MODULE.md。
⚠️ TCP_WEBGL_HANDOFF.md当前不在工作区(git status显示D,即被 git 追踪但工作区已删;不是本会话删的, 也不在本会话的清理范围内)。它是本文件多处引用的 TCP 权威文档,新会话需要它时按下面任一种取:
- 从 git 恢复:
git checkout -- TCP_WEBGL_HANDOFF.md(HEAD 内容 105 行,完整)- 或读副本:
D:\Users\Administrator\Desktop\notd\TCP_WEBGL_HANDOFF.md(105 行,内容一致)- 其它工程副本:
D:\unity project\pinball-learning-{code,source,source-clean}\TCP_WEBGL_HANDOFF.md若要恢复,请先确认它是有意删除的(
AGENTS.md§3:不清理负责人已有改动)。
网络:已走通,且有权威文档 —— 不要重新发明
- 平台 API 是微信
TCPSocket(WXBase.CreateTCPSocket()+OnConnect/OnError/OnClose/OnMessage/Write)—— 不是 WebSocket,因此不需要 TCP-over-WS 网关。 TCP_WEBGL_HANDOFF.md明确记录:历史日志曾证明「网关获取 → TCP 建连 → 握手 → 游客登录 →GetHero收包解析」全链路跑通;后来被临时改动弄坏了探针。- 2026-09-22:该全链路已在微信小游戏容器内再次跑通,六包齐全(见本节「最新状态」表)。修复过程与证据链见
TCP_NETWORK_BREAK_ROOTCAUSE.md。 - 探针 =
Assets/Client/Runtime/ClientTcpConnectionProbe.cs(挂在Boot.unity的Init对象上,独立验证用,不替代原业务登录流程)。它靠自身StartPersistentProbe()迁移到DontDestroyOnLoad对象以存活过场景切换。 - ↔ 探针的反射目标
NetController/SysDefines在 HotFix 程序集里,而 HotFix 只有Boot/Init能加载(Init.cs:216Assembly.Load)。 ⇒ 因此探针必须与Init同场景;任何"绕过Boot的客户端独立入口"都会让探针 15 秒超时。这是一条硬约束。 ⚠️ 文档明令的硬约束:① 不得再用“直接引用 HotFix 类型”解决反射问题(会复发 IL1005 / 程序集解析失败);② 不得改 IP / 端口 / 服务端 / 账号 / token / YooAsset 基础设施 / 微信 SDK / 项目设置(例外:负责人 2026-09-22 已授权为移植目标修改MiniGameConfig.asset的 CDN 与构建清单);③ 没有新日志证据时不得反复改端口、随机改协议字段或宣称成功。- 成功判据是带前缀的日志(
[TCP客户端] …),末尾必须出现“英雄数据接收并解析成功”+“成功退出 TCP”;禁止把“已建连 / 已握手 / 已登录 / 连接关闭”当作整体成功。 - 收尾流程:
run-pipeline-2phase.ps1→ 按OSS_UPLOAD_MANIFEST.txt上传(YooAsset 文件放 CDN 根目录)→ 清开发者工具缓存 → 重跑 → 回传完整[TCP客户端]日志。
基础设施:已就位(2026-09-20 代理只读清点,勿重复搭)
| 项 | 证据 |
|---|---|
| 微信 SDK | Assets/WX-WASM-SDK-V2(含 Editor/WXConvertCore.cs) |
| WebGL 资源包 | Bundles/WebGL/DefaultPackage 719.5 MB,OSS/CDN 链路已通 |
| 热更 | HybridCLRData/{Assemblies,HotUpdate,il2cpp,StrippedAOT,LocalIl2cpp…} 有 WebGL 数据 |
| 原生插件 | 工程内已有 .jslib / .wasm |
| XLua 风险 ≈ 0 | WebGLPlugins/ 有完整 Lua 5.3 C 源(能在 WebGL 编译);但 Assets/Lua 只有 7 个文件 / 1.2 KB ⇒ Lua 基本没用,逻辑是 C# |
难度评估(依据上述证据,不是猜测)
- 目标 A「真机主流程跑稳」≈ 1.5 ~ 3 周;目标 B「可提审(全机型 / 弱网 / 性能 / 合规)」≈ A 之后再 2 ~ 4 周。
- 风险排序:① iOS 真机 WebGL2 / 内存 / 纹理压缩;② 包体与首启下载体验(首包 ≤ 4MB、wasm 走 CDN);③ HybridCLR AOT 泛型补齐(新 API 会冒一次);④ UI 适配(刘海 / 长屏 / 安全区);⑤ 音频解锁 / 触摸 /
onShow-onHide。 - 待负责人回答(直接改工期 ±1 周):那次 TCP 成功是真机还是开发者工具?
BUG-009(首屏黑屏 + URP shader)与BUG-013(app.json启动页)现在是否真的闭环(tracker 仍标“调查中”,确认后请关闭)。
加载页:UI 侧已备好,只等启动流程接线
- 新增
Assets/Client/Runtime/ClientLoadingService.cs:Begin(text)/SetProgress(0..1)/SetProgressPercent/SetLoadingText/Complete()/Hide();它显式接管SystemLayer开关(该层恒 inactive,而加载Page自身activeSelf=1,一激活就全屏显示)。 - 接线点 =
Assets/Main/Init.cs的资源下载:OnDownloadProgressUpdateFunction第 405 行已算出progress,目前只Debug.LogError(progress)(每帧刷 error);把注释掉的EventTrigger换成ClientLoadingService.SetProgress(...)即可。 ⚠️ Init.cs属启动 / 原公司代码边界,UI 会话未动它。- 演示入口(Play 模式):菜单
Client/加载页/演示 5 秒加载(走 ClientLoadingService)。
HANDOVER_PLAN.md §3 规定 SystemLayer 承担「Loading / 阻断遮罩 / Toast / Tips」,但 SystemLayer 在场景里恒 inactive;因此 2026-09-20 把全局 Toast 与 ClientSystemFeedback 移到了 ClientCanvas/ToastRoot(否则 Toast 不显示、StartCoroutine 直接报错)。要么按 plan 恢复(让加载/提示流程显式控制 SystemLayer.SetActive),要么修订 plan 把 Toast 归到 ClientCanvas —— 请负责人定,别两边都写。
UI 侧现状(新会话别重做)
- 已整页验收:
HeroPage英雄、FormationPage编队;ShopPage商店/MailPage邮件早已模板化。 - 已验收细节(编队):点卡即切换(自动补编号最小的空位 / 再点移出且不补位 / 满员不加入 / 同队不可重复英雄);队内编号
1..3显示在选卡上(数字贴图Assets/Client/UI/HeroDetailPage/Sprites/属性icon/新建文件夹/数字/0..9.png,换 sprite 实现);空槽保留格位、清空卡面;选中点用 alpha 高亮;确认键= 确认并返回。 - 未做 / 阻断:
ActivityPage结构收敛(行为已正确,需一次场景写入)、ProfilePage(真列表无数据源,见MODULE.md§14)、RankPage等;元素筛选负责人明确不做。 - 全局 Toast 已可用;
ClientPopupService._maskRoot(弹窗遮罩槽位)仍为空。
这是什么:游戏权威配置(不是草稿)。excel\1服-弹珠\ 下 20 张 .xlsx(Hero 140 KB、Resources、Skill、Potency、MapCopy、Item、Head、HeadFrame、Badge、Nameplate、Title、Energy、Dan、Coefficient、Monster、MonsterTemplate、PinBallRoom、RandomHero、PotencyLevel、Audios、ServerControl),并为 Client / Server 各生成 4 种产物:Cs(生成类)/ Json(真实数据)/ Lua / Cpp。同目录 弹珠配置\tools 是导出器与协议生成器(jbproto,含 GlobalProtocols.xml、ClientPF.xml 等协议定义与 175 KB 的 ClientPF.cs)。
它解开了哪些此前的"未定义/阻断"
MODULE.md§14 关于个人中心真列表的"条数来源 / 拥有规则 / 图标映射 / 排序全部未定义" —— 其实全有定义:Head / HeadFrame / Badge / Nameplate / Title五张表同一形状:Id / Name / Desc / Sorting(排序)/ ClientShow(前端是否显示)/ NotUnlockedClientShow(未解锁是否显示)/ ResId(美术资源);Head用字符串Avatar代替ResId。- 排行榜精灵表(BUG-019):
THero提供QualityIcon_3..6、ElementIcon_1..6、CatapultIcon_1..3、Avatar(HeroAvatar_13001)、Portrait1/2(HeroPortrait_13001_c/_d) —— 美术按名字约定,可按名解析,不必手拖数组。 - 元素筛选:
THero.Element是 int 1..6(不是"Fire"/"Water")⇒ 编队页那 7 个按钮 =全+ 6 元素,数量吻合,"映射未定义"这条可解(只差 int↔中文名的顺序确认)。
真实契约 vs 我们前端当前的假设(需对齐)
| 项 | Assets/Client 现状 |
权威契约 |
|---|---|---|
| 英雄 Id | string "hero-001" |
int(如 13001) |
| 元素 | string "Fire"/"Water" |
int 1..6 + ElementIcon |
| 品质 / 弹射 | 未用 | int 3..6 / int 1..3 + Icon |
| 英雄规模 | 本地模拟 9 个 | Hero.json 54 行,且带 ClientShow 前端可见门 |
| 立绘 / 头像 | 未接 | 名字约定 HeroAvatar_<id> / `HeroPortrait__c |
发现的缺口(已核实)
- 工程
Assets/Scripts/Table/缺 4 个生成类:TBadge/TNameplate/TPotency/TPotencyLevel—— 配置目录里有,工程里没有;且TableLoadConfig.TableHelperTypeList的 17 张清单里也没有它们 ⇒ 徽章 / 铭牌永远没有数据源(这不是"待确认",是缺文件)。 - 工程里一个表 JSON 都没有(全
Assets无Hero.json等,也没有Resources/Table目录)⇒TableLoadHelper走"本地配置表缺失,使用空表继续"分支(TableLoadHelper.cs第 233~241 行),17 张表全空。当前 ClientShell 场景日志里该警告 0 次,因为表加载挂在启动流程(TableManager/GameController)上,本场景不跑。 - 待验证的加载契约:
THero等类把levelCap / HpBase / Skill …声明为JArray,而 JSON 里是字符串("levelCap":"[10,20,30,40,50]")⇒ 加载器必须做转换,否则这条会在接真表时炸。
待负责人定
- 表的投放:两者(已定,见下「第 50 轮」)
- 是否补齐那 4 个生成类并加入
TableLoadConfig清单?(已定:可以) Assets/Client与表的边界(已定:表驱动)- 元素
int 1..6↔ 中文名(光/水/土/风/火/暗)的顺序以哪个为准? ← 仍未定
第 50 轮 · 表驱动落地(已执行并验证)
- 负责人三项决定:表投放 = 两者(本地进包兜底 + OSS
config.pkg热更);Assets/Client= 表驱动;补齐 4 个生成类 = 可以。 - 补齐/修正工程表类(
Assets/Scripts/Table/,均只增不删,因为原项目代码在用):- 新增 4 个此前缺失的生成类:
TBadge/TNameplate/TPotency/TPotencyLevel(从配置目录拷入,using规范成工程的LC.Newtonsoft.Json.Linq),并加入TableLoadConfig.TableHelperTypeList(原清单 17 张 → 21 张)。 THero:补Portrait1(卡面) /Portrait2(出战位);保留旧Portrait——Assets/Scripts/BNRoom/UI/MarbleUI.cs:1148仍在读它,删掉会破坏原项目编译。THead:补Desc / Sorting / ClientShow / NotUnlockedClientShow+Avatar(新表以资源名替代整型ResId),保留ResId;THeadFrame/TTitle同样补前四个字段。⚠️ 这三个类的工程版本是旧版(只有Id/Name/ResId),不补就没有ClientShow/Sorting/NotUnlockedClientShow—— 「表驱动」的过滤与排序规则全依赖它们。
- 新增 4 个此前缺失的生成类:
- 本地表进包:21 张 JSON 落到
Assets/Resources/Table/(合计 174.1 KB)。已确认Assets/Resources不在 YooAsset 收集路径里(收集的是Resources_HotUpdate/与HotUpdateResources/)⇒ 不会产生 BUG-012 那种重复资源地址。 - Client 侧表驱动:新增
IClientConfigService+ClientConfigModels(ClientHeroConfig/ClientCollectionConfig/ClientCollectionKind)+TableClientConfigService,并在ClientServices暴露Config。UI 只依赖接口,不直接引用原项目表类型。⚠️ 实现走反射,不直接引用 HotFix 类型:表类在HotFix程序集(Assets/Scripts/HotFix.asmdef),而Assets/Client属Assembly-CSharp。TCP_WEBGL_HANDOFF.md明确禁止直接引用(会复发 IL1005);且工程里的HotFix.ref.dll是上次构建产物,直接引用会读到旧成员(本轮实际踩到:THero少了Portrait1/2导致 23 个编译错误)。
- 新增只读探针
Assets/Client/Editor/ClientTableProbe.cs(菜单Client/配置表/打印各表行数+-executeMethod两用,全程反射):把每张表的真实行数打出来。它是"表到底加载没有"的唯一可靠入口 —— 底层TableLoadHelper缺表时只打一条警告就按空表继续,UI 会安静地什么都不显示。 ⚠️ 重大发现:磁盘缓存config.pkg优先级高于本地 json。TableLoadHelper.LoadFromLocalPackage()先看{persistentDataPath}/config.pkg,存在就用它,本地Resources/Table/*.json只是"没有缓存时"的兜底。 实测:C:\Users\Administrator\AppData\LocalLow\xiaoshi\xiaozhen\config.pkg(2026-09-03,9.3 KB,9/3 WebGL 调试遗留)一直盖着新表 ⇒ 探针只报THero = 12 行(而非 54)。 已备份到Logs/config.pkg.bak-20260903后删除,重跑探针 ⇒THero = 54 行、21 张表全部可用(0 空表 / 0 缺失)。 含义:只更新本地 json 不会生效,只要还有旧缓存;生产靠LoadFromNet(ossUrl, md5)按 md5 覆盖缓存(localPackageMd5_ != remoteMd5才下载)。小游戏真机同理。- 表行数实测(
Logs/table-probe-2.log):Hero 54、Resources 256、Potency 68、Skill 33、Audios 29、MapCopy 24、Monster 15、MonsterTemplate 12、HeadFrame 9、Title 9、Item 9、Head 6、Badge 6、Nameplate 5、RandomHero 4、PotencyLevel 3、其余 1 行(Energy/Coefficient/PinBallRoom/ServerControl/Dan)。ClientShow=1的英雄有 49 个。 - 验证证据:①
Logs/verify-compile-tables3.logRoslyn 三目标 0 error;②Logs/table-probe-2.log命令行 Unity 全工程编译 0 error(覆盖HotFix,满足 AGENTS.md 对编译输入改动的要求)+ 21 张表行数;③ 探针 0 次「本地配置表缺失」。 ⚠️ 工具盲区(已确认,供后续会话):Logs/verify-compile.ps1的编译清单取自Library/Bee/artifacts/*/Assembly-CSharp.rsp,只覆盖Assembly-CSharp(Assets/Client),Assets/Scripts(HotFix程序集)不在其中 —— 它引用的是旧HotFix.ref.dll。所以改Assets/Scripts必须用命令行 Unity 编译或表探针那条路验证,否则会看到"改了却不生效"的假象。- 下一步(UI 侧,等负责人放行):把
HeroPage/ProfilePage/RankPage从本地模拟切到ClientServices.Config(54 英雄、真头像/徽章/称号),玩家状态仍走IClientDataService;ClientPlayerProfile.EquippedTitleId/EquippedAvatarId目前是 string,与真实契约的 int Id 不一致,切换时需一并改。 - 第 50 轮补(诊断要主动出现):
ClientServices.InitializeForDevelopment()里改为立刻触碰一次_config.IsReady,让配置表在启动时就加载并打印行数。⚠️ 首轮负责人 Play 时 Console 什么都没看到 —— 因为TableClientConfigService是懒加载,而当时没有任何页面调用Config,所以Report()从未执行。教训:诊断日志不能依赖"有人来查询",否则表加载失败(底层只打一条警告就按空表继续)会毫无线索。已修,Roslyn 三目标 0 error(Logs/verify-compile-eagerconfig2.log)。 - 第 51 轮 · 发现工程表类与实际配置表「结构漂移」(99 条运行时 FormatException)
- 负责人 Play 后 Console 出现 99 条
配置表解析出错:System.FormatException。定位到字段级:Skill.json33 行 ×Effect1Subtype/Effect2Subtype/Effect3Subtype(工程类 =int,json ="[]")⇒ 33×3 = 99 ✓ 完全吻合。配置目录的新TSkill.cs已把它们改成JArray,并删除*SubtypeParameter、新增*ResId/Attack。 - 全表漂移普查(固化脚本
Logs/verify-table-drift.ps1,只读可复用):Resources(256 行:SkeletonData被丢弃,ScaleX/ScaleY/ScaleType/ActionName/AnimationName/BbWidth/BbHeight/Int恒 0)、RandomHero(Heroid被丢弃、Weight恒 0)、Coefficient(SkillBeneficialEffect/SkillNegativeEffect被丢弃)、MonsterTemplate.Rewards恒 0。Hero.Portrait/Head.ResId是本轮刻意保留的兼容字段(预期内)。 - 修复牵涉战斗代码,本轮未动:
Assets/Scripts/BNRoom/Static/GetSkillEffectParameters.cs:48~53把Effect1/2/3Subtype与*SubtypeParameter当int用,改成JArray会破坏战斗技能参数装配 ⇒ 属原公司战斗逻辑,超出授权,需负责人裁决(BUG_TRACKER.mdBUG-022 给了三个备选方案)。 ⚠️ 我的验证疏漏(已记BUG_TRACKER.mdRISK-019):Logs/table-probe-2.log里本来就有 99 条配置表解析出错(含堆栈共 198 行),但我当时只 grep 了error CS,于是对外报"0 error"—— 报告失真,负责人 Play 时立刻看到。纪律:批处理/Play 之后必须同时扫Exception与业务LogError关键字(本项目为配置表解析出错、本地配置表缺失),再下"0 error"结论。- 另修:
Logs/verify-table-drift.ps1第一版用@(管道 | ConvertFrom-Json),在 PowerShell 5.1 下会把顶层 JSON 数组裹成1 个元素,逐字段报告全是Count/Length/Rank这类数组自带属性(假数据)—— 已改为正则提取并自检行数(Hero=54、Skill=33)。验证脚本本身写错比没有更糟,本轮已第二次踩到。
- 负责人 Play 后 Console 出现 99 条
- 第 52 轮 · 按负责人边界重构:Client 自己读表,不再触发全量加载(99 条报错从根上消失)
- 负责人 2026-09-20 明确边界:只负责
Assets/Client的实现与平台移植,其余一律不管,除非挡到这两项。 - 判断:那 99 条来自
TableManager.InitData()的21 张全量加载,其中Skill表 Client 根本不用 ⇒ 属"挡到 Client 验收"(Console 被刷满),因此在 Client 侧隔离,不动战斗代码。 - 新增
Assets/Client/Runtime/Services/ClientTableSource.cs:客户端自己的读表入口,数据源优先级与游戏一致 ——{persistentDataPath}/config.pkg(远端热更落盘)优先 →Resources/Table/<表名>.json(进包兜底)。pkg 格式为只读复刻(GZip →version:1byte→ 反复[utf8\0][utf8\0];权威实现TableLoadHelper._parsePackageContent),版本不符/解析失败回退本地并警告一次。 TableClientConfigService重写:改为用LC.Newtonsoft.Json.Linq(插件 DLL,不属 HotFix)直接解析;不再反射T*Helper/TableManager,不再触发 21 张全量加载。字段读取全部容错(缺失/类型不符回落默认值,不抛异常)。ClientTableProbe重写:不再反射 HotFix,改走ClientTableSource验证客户端真实路径;菜单更名Client/配置表/打印客户端配置表行数;日志前缀[配置表]。- 验证(
Logs/client-table-probe.log,本次按要求同时扫运行时报错):error CS0;配置表解析出错0(原 99);Exception/FormatException/NullReference0;本地配置表缺失0。 ·Hero = 54 行(ClientShow!=0 的 49 行)、Head 6(1)、HeadFrame 9(3)、Badge 6(1)、Nameplate 5(1)、Title 9(1);汇总 6 张可用 / 0 空 / 0 缺失 / 0 解析失败;数据源 = 本地Resources/Table(磁盘上已无config.pkg)。 ⚠️ 待负责人确认(数据侧,不是代码问题):按表里的ClientShow规则,前端只显示 1 个头像 / 3 个头像框 / 1 个徽章 / 1 个铭牌 / 1 个称号(连Head的"默认头像"Id=1都是ClientShow=0)。英雄侧 49/54 正常。这像是配置尚未填全,而非规则有误 —— 请确认是要按现数据照做,还是等配置补齐。- 影响:
BUG-022(表结构漂移)对 Client 已不再有影响(已隔离),仍对战斗侧有效但按边界不在本次范围;BUG-021(旧config.pkg覆盖)仍要注意 —— Client 也会优先读落盘 pkg。
- 负责人 2026-09-20 明确边界:只负责
- 第 53 轮 · 按配置对齐客户端(int id 全量切换 + 表驱动落地)
- 负责人三项决定:id 全改 int(原选项 A)/元素
1..6= 光/水/土/风/火/暗(按筛选按钮排列)/战力先标待确认。 - 领域模型:与配置对应的 26 个字段转
int(英雄 / 道具 / 收藏品 / 技能潜能 / 编队槽位 / 卡池奖励 / 奖励道具 / 升级消耗资源)。 服务端不透明标识(订单 / 邮件 / 活动 / 任务 / 公告 / 卡池 / 商品 / 玩家)与美术资源名(IllustrationId/AttributeIconId/QualityId,配置给的就是名字如QualityIcon_3)保持string。 对应地,IClientDataService的相关签名全部改为int(GetHeroDetail/TryUpgradeHero/TryToggleFormationHero/TrySetFormationSlot/GetShowcaseHeroId/GetEquippedBadgeId…)。 - 元素:新增
ClientElements(1..6 = 光/水/土/风/火/暗,含Name/FromName/AllIds);ClientHero.Element(string) →ElementId(int) +ElementName(中文名) +ElementIcon。 已核实.Element全工程没有任何调用点(只有一处注释引用),因此改动无回归面。 - 表驱动落地:
LocalClientDataService里 9 个手写假英雄 →BuildHeroesFromConfig():静态字段来自配置表(名字 / 品质 / 元素 / 星级 / 图标名 / 立绘名),玩家状态本地模拟(拥有 = 前 6 个、等级 = 1、战力 = 0【待确认】)。 - 收藏品接口:新增
GetOwnedCollectionIds(kind)/GetEquippedCollectionId(kind)/TryEquipCollection(kind, id)—— 列表来自ClientConfigService.GetCollections(配置 +ClientShow/Sorting),拥有/装备是玩家状态;TrySetEquippedBadge改为转调它;顺手修掉GetEquippedBadgeId()原本错误地返回称号的 bug。 ⚠️ 抓到并修掉一个初始化顺序 bug:InitializeForDevelopment()里_data先于_config创建,而IsInitialized => _data != null,导致构造LocalClientDataService时守卫为 false ⇒ 现象是"配置能读到 49 个英雄,数据服务却报英雄配置为空"。已改为先建配置服务再建数据服务,并新增ClientServices.HasConfig供构造期判断。- 验证(
Logs/client-config-chain2.log:命令行 Unity 全工程编译 + 探针,按新纪律一并扫了运行时报错):error CS 0/Exception 0/配置表解析出错 0;英雄列表 = 49 个;首个 = Id 13003 / 蝎子精 / 元素1(光) / 品质3 / 1星 / 拥有=True / 战力=0【战力待确认】; 收藏品:Head 可见1/拥有1/装备10001、HeadFrame 3/2/10002、Badge 1/1/10002、Nameplate 1/1/10001、Title 1/1/10002。 - 仍未接(下一步):① 英雄详情接
TSkill/TPotency;② 道具/背包接TItem并修正ClientItemType语义(Type=1实为货币、Type=2表里没有);③ProfilePage用新的收藏品接口做列表收敛(含场景写入);④ 立绘按名加载(HeroAvatar_*工程内 0 个、HeroPortrait_*仅 8 个 ⇒ 缺图,不报错但显示为空)。
- 负责人三项决定:id 全改 int(原选项 A)/元素
- 第 54 轮 · 修「图鉴仍显示 55/99」与「英雄页只有 6 个」
- 负责人 Play 反馈:真实英雄名出来了 ✓;但英雄页只显示 6 个、图鉴仍显示 55/99。
- 55/99 的根因:场景里每个子页各有一套进度文本 ——
HeroPage英雄/HeroSubPage/upCanvas/底框Image/{已收集进度, 总英雄数量}与HeroPage英雄/GuideSubPage/upCanvas/底框Image/{已收集进度, 总英雄数量}, 两套的设计文案都烘死为55与/99;而ClientHeroPage在 Inspector 上只接了一套(_ownedProgressText/_totalHeroCountText指向HeroSubPage那套)⇒ 另一个子页(图鉴)永远停在烘死文案上。 修法:RefreshProgress()改为按两个子页根节点各自深度查找(FindDeepChild)并两套都写,口径 =已收集(已拥有英雄数) +总数("/" + 英雄总数);Inspector 上原槽位保留兼容写入。纯代码,未写场景。 - 只显示 6 个的根因:英雄子页按既有设计只列已拥有(图鉴列全部、未拥有带锁),而我上一轮的模拟只让 6 个英雄"已拥有"。
改为
SimulatedLockedHeroCount = 3(除最后 3 个外都视为已拥有) ⇒ 英雄子页 46 张、图鉴46/49,且仍能看到 3 张未拥有的锁态。⚠️ 拥有状态属玩家状态,真实值应由服务端下发;这里只是演示模拟。 - 顺带记录:
已收集进度/总英雄数量四个节点都在 prefab 实例里(组件 fileID 是 19 位长 ID,场景内查不到组件文档)—— 这正是"只读工具看不到 prefab 实例内部"的老盲区,故改用运行时代码查找而非 Inspector 接线。 - 验证:Roslyn 三目标 0 error;命令行 Unity 全工程编译 + 探针见
Logs/client-config-chain3.log。 - 请 Play 复核:英雄页应显示 46 张;两个子页右上角都应显示
46/49(不再是 55/99)。
- 第 55 轮 · 卡面名称节点迁移(取消名称底图;范围=全改)
- 负责人要求:"取消英雄名称的 image,然后调一下 text 的显示",范围 全改(= 改共用的卡prefab,所有引用处一起变)。
- 机制说明(回答"名称是不是代码写的"):是 ——
ClientHeroCard._nameText.text = displayName,_nameText是序列化字段。 原 prefab 里只有卡牌名称Image(纯 Image,没有文本子节点),名称 TMP 是修复工具在场景实例里新建的(路径卡牌名称Image/卡牌名称)⇒ Image 是名称文本的父节点:直接删 Image 会把文本一起删掉、_nameText静默变 null(名称消失且不报错)。 - 执行:新增幂等步骤
MigrateCardNameNode()(已挂进RepairAll,位于WireHeroCard之后、CreateGuideSubPage之前): ① prefab 本体新建卡牌名称(锚点/尺寸/位置沿用原 Image ⇒ 文字落在原处)→ ② 删 prefab 的卡牌名称Image→ ③ 场景侧把残余卡牌名称Image下的文本上提一级(继承 Image 矩形)后删 Image → ④ 对每张ClientHeroCard重新接线_nameText。 ⚠️ 实测发现(重要):只改 prefab 不够 —— 第一轮跑完场景里仍有 4 处卡牌名称Image(FormationPage编队卡牌-Panel的 3 张槽位卡 + HeroPage 图鉴子页的模板卡),说明它们并不是该 prefab 的实例、prefab 改动不会传播过去。 ⇒ 第 ③ 步刻意不依赖 prefab 血缘,改为按节点名在全场景处理(已是通用、幂等)。- 验证(
Logs/repair-namemigrate2.log):error CS 0、配置表解析出错 0;场景卡牌名称Image = 0(期望 0 ✓)、卡牌名称 = 6;5 张ClientHeroCard全部名称=卡牌名称✓;无"卡下没有卡牌名称"警告 ✓;共 22 处变更。 - 备份:
Logs/角色卡牌Button-final 1.before-namemigrate.prefab.bak、Logs/ClientShell.before-namemigrate.unity.bak、Logs/ClientShell.before-namemigrate2.unity.bak。 - 顺带加固:
WireHeroCardOn()原来写死卡牌名称Image路径找名称节点,找不到就把_nameText写成 null(静默失效);已改为整卡子树按名深搜,找不到才回退旧路径创建 ⇒ 以后无论怎么挪节点,RepairAll都不会冲掉接线。 - 待确认:名称文本的字号/颜色/对齐/位置是否还要调 —— 当前沿用工具默认(居中、20pt、黑色、
raycastTarget=false,矩形 = 原 Image)。
- 第 56 轮 · 继续接配置:道具 / 技能 / 天赋 / 随机英雄池 进入客户端模型
- 负责人:"改好了这个,继续其他配置"。
- 领域模型:新增
ClientItemConfig(道具)、ClientSkillConfig(技能)、ClientPotencyConfig(天赋/潜能)、ClientRandomHeroConfig(卡池);ClientHeroConfig增Skills/Potencies(来自THero.Skill/THero.Potency,即"本英雄的技能/天赋 id 列表")。 - 接口:
IClientConfigService增 7 个只读查询 ——GetItems/TryGetItem/TryGetSkill/TryGetPotency/GetHeroSkills/GetHeroPotencies/GetRandomHeroPool;TableClientConfigService全部实现,并新增ReadIntList兼容表里两种数组写法(真数组 与 字符串形式"[10,20,30]")。 - 探针表清单 6 → 10 张(加
Item/Skill/Potency/RandomHero)。 - 验证(
Logs/client-config-items.log):error CS 0、配置表解析出错 0;Item 9 / Skill 33 / Potency 68 / RandomHero 4全部读到(汇总 10 张可用 / 0 缺失 / 0 解析失败);英雄 13003 技能 4 个;首个 = 130011 捣药杵击 / Type1✅(表间关联可用);道具 9 个;首个 = 110001 点数 / Type1 / Item_110001✅;随机英雄池 4 条;首条 = 池1 -> 英雄 15001✅。 ⚠️ 两个数据发现(已记MODULE.md§15.6,待负责人确认,未确认前不写映射):- 天赋数据只有 4 个英雄填了:
13001 玉兔(13 个) /14001 嫦娥(17) /14007 唐三藏(17) /15001 孙悟空(21),id 属300101/400101/400701/500101系列; 其余 50 个英雄的Potency是占位[1,2](表里最小 id 是300101)⇒ 解析为 0 条。客户端已容错(不报错、返回空集合),表现为天赋页无数据 —— 需确认是"数据未填"还是"另一种引用约定(如按行号)"。 - 技能
Type↔ 详情页天赋 / 秘技 / 终结技的冲突(无权威依据,未写映射)。⚠️ 纠正上一版的误导说法:先前写"54/54 个英雄的技能关联全部可解析"——技术上成立但会误导,真相是 54 个英雄的Skill只有 4 种取值,同一"系列"的英雄(16 / 6 / 16 / 16 个)共用同一套技能;天赋同理,只有 4 个"系列首个英雄"填了。 被英雄引用的 16 个技能 = 4 个系列 ×Type 1/2/3/4各一个:Type1主动攻击(捣药杵击 / 月轮飞击 / 禅杖普度 / 如意金箍棒)、Type2回复·增益(玉兔灵药 / 月华祝福 / 佛法回复 / 战意昂扬)、Type3被动·护体(月华追踪 / 广寒清辉 / 金蝉护体 / 金刚不坏)、Type4大招(广寒月影 / 皓月当空 / 紧箍咒 / 法天象地)。 另有 17 个技能没有任何英雄引用(Type5×16 +Type6×1 +999999 占位),描述全是"对敌人造成伤害"、名字是怪物名(火焰追击 / 毒牙毒液 / 蛮牛冲撞 / 九头齐噬…)⇒ 那批属怪物(战斗侧)技能。 ⇒ 冲突 = UI 的 3 个页签 vs 配置的 4 类技能 + 1 个天赋列表:① 数量:4 类要塞进 2 个技能页签,即便Type4= 终结技,Type1/2/3三类也只能挤进「秘技」;② 归属:Type本身不区分英雄/怪物(靠值域1~4/5~6),映射无法只从Type推出;③ 形态:TPotency是每英雄 13~21 条的列表,页签呈现方式无依据。详见MODULE.md§15.6。
- 天赋数据只有 4 个英雄填了:
- 未做(等答复再动):
ClientHeroDetailPage用真实技能/天赋渲染;ClientItemType的语义修正(实测Type=1是货币、Type=3是消耗品,Type=2表里没有,客户端现叫Material(1)/Equipment(2)/Consumable(3))。
- 本次会话收尾(2026-09-20 晚)
- 负责人决定:
- 天赋占位
[1,2]⇒ 空着就行、不要报错(已确认为预期行为,不是缺陷)。客户端当前行为即如此:GetHeroPotencies静默跳过查不到的 id、返回空集合,不打日志、不抛异常;探针实测英雄 13003 天赋 0 个且error CS 0/配置表解析出错 0/ 无异常。已在代码处加注释固化,防止后人当成 bug"修"成按行号取或补默认值。 - 技能
Type↔ 秘技 / 终结技 的对应:负责人在问,明天再定。 未确认前不写映射。
- 天赋占位
- 下一步(明天):
- 拿到技能
Type映射后,接ClientHeroDetailPage的 秘技 / 终结技 页签(Config.GetHeroSkills(heroId)已就绪)。 - 天赋页签接
Config.GetHeroPotencies(heroId)(4 个英雄有数据、其余按约定显示空态)。 ClientItemType语义修正(Type=1货币 /Type=3消耗品 /Type=2表内无)—— 方向已获同意,改名与用法待做。- 其余待接:
ProfilePage收藏品列表收敛(需一次场景写入)、立绘按名加载(HeroAvatar_*工程内 0 个、HeroPortrait_*仅 8 个 ⇒ 缺图,取不到时显示空、不报错)。
- 拿到技能
- 今日产出(可交付状态):
Assets/Client已表驱动—— 10 张客户端表(Hero / Head / HeadFrame / Badge / Nameplate / Title / Item / Skill / Potency / RandomHero)读入客户端模型,48 个英雄真实数据在 Play 中可见,收藏品接口(列表来自表、拥有/装备属玩家状态)可用,卡面名称底图已按要求取消且接线加固。全部经命令行 Unity 全工程编译 + 探针验证(Logs/client-config-chain*.log、Logs/repair-namemigrate2.log)。
- 负责人决定:
- 第 90 轮 · 大厅窄高比适配(背景黑边 + 两个底栏重叠):根因已确证、修法已编译,待应用
- 负责人反馈:大厅在 1080×2160 / 1080×1920 上背景左右黑边、
CanvasBottomFunction0与CanvasBottomFunction1靠近至重叠;752×1630 ~ 1080×2280 正常。 - 根因(实测数据,非推断):
ClientCanvas参考753×1630、matchWidthOrHeight = 0(按宽匹配)⇒ 画布宽恒 753、高 = 753×(H/W): 2.168→1632 ✓ / 2.111→1590 / 2.0→1506 / 1.778→1339。 ·MainPage主页/Background是全屏锚点 ✓ 但Image.m_PreserveAspect = 1⇒ 画布变矮时按高缩放 ⇒ 比 753 窄 ⇒ 左右黑边; ·CanvasBottomFunction0锚点 (0.5,0)(底)而CanvasBottomFunction1锚点 (0.5,0.5) + offset -417(中)⇒ 后者随画布中心下压: 高 1630 时二者中心距底 398 / 227(间距 171 ✓);高 1339 时 F1 降到 252.5 ⇒ 半高 97/87.5 ⇒ F0 顶边 324 > F1 底边 165 ⇒ 重叠 ✓ 与"比例越矮越严重"完全吻合。 - 修法(工具
NormalizeLobbyBackgroundAndBottomBars(),纯锚点机械修正、不动美术尺寸/位置): ① 背景preserveAspect = false(铺满;若要保比例可改用AspectRatioFitter.EnvelopeParent做"覆盖"); ②CanvasBottomFunction1改底锚、offset 取设计高度等效值 398(=1630/2−417)⇒ 两者都跟底边走,间距恒定。 - 状态:代码已写好、编译三目标 0 error ✓;备份
Logs/ClientShell.before-lobbyadapt.unity.bak✓。 ⏸ 场景写入未执行:负责人正在编辑器里,批处理因"工程已打开"中止(HandleProjectAlreadyOpenInAnotherInstance)。 ⇒ 可由负责人一键应用:菜单Client → 结构修复 → 2. 执行结构修复(幂等,含本修正);或关掉编辑器后由我执行 + 补跑自检。
- 负责人反馈:大厅在 1080×2160 / 1080×1920 上背景左右黑边、
- 第 89 轮 · 交付《UI 锚点定稿确认表》—— 19 页可"所见即所得"直接微调
- 负责人要求:"确定哪些界面的布局锚点已经定好、能所见即所得,我直接微调就完事" ⇒ 交付
UI_ANCHOR_SIGNOFF.md。 - 内容:21 页逐页定稿状态表(根/背景 · 底栏 · 标题/顶区 · 列表容器 ⇒ 结论)+ 4 条微调注意事项 + 已定稿的 7 条锚点规则 + 复现命令。
- 结论:19 页 ✅ 可微调 / 2 页 ➖ 未接入(
Email Details (Have)/(No));另Success Receipt Interface不可达。 - 4 条注意事项(避免白改):① 面板式弹窗别改成全屏(会盖住下层)② 列表
Content的高度由运行时撑开(手改高度会被覆盖;改CellSize/Spacing/Padding安全)③ 改锚点必须保持全屏拉伸(弹窗遮罩只改颜色、别改尺寸)④ 卡牌网格保持UpperLeft。 - 数据来源:本会话两批只读核查(
ui-adapt-audit.ps121 页 /ui-adapt-audit2.ps115 个标题节点)✓ 可重跑。 - 本轮无场景/代码改动;编译与自检保持上一轮状态(96/0)。
- 下一步:负责人按该表逐页微调视觉;遇到具体错位时给页面 + 截图,我做定点修正(流程:定位根因 → 最小改动 → 编译/自检 → 复验)。
- 负责人要求:"确定哪些界面的布局锚点已经定好、能所见即所得,我直接微调就完事" ⇒ 交付
- 第 88 轮 · UI 适配第二批:标题贴顶 / 顶区对齐 —— 无真问题(结构规则已达标)
- 新增
Logs/ui-adapt-audit2.ps1(只读)→Logs/ui-adapt-audit2.md:核对 15 个 title/top-bar 节点是否顶部锚定、是否被错挂在Bottom page function bar下(后者是历史坑:会随画布高度变化与顶区重叠)。 - 结果:无真问题 ✓
· 没有任何节点被错挂在底栏下 ✓(历史坑已消除);
· 真正的页面标题都已顶部锚定:
ShopPage商店/Shopping Mall Title✓、MailPage邮件/Email Title✓、ActivityPage活动/task title✓、Complete Guide Event Page全图鉴活动/task title✓、ShopPage商店/Top function bar✓; · 其余报not top-anchored的是标题背景框 / 弹窗内部标题 / 装饰节点(如Shop title background frame、Emial title background frame、RenameDialog/Title、Content_Title)—— 它们本就不需要顶部锚定,是我校验收得太宽(判据假阳性)。 - 结论:UI 适配的"结构性规则"已全部达标(画布按宽匹配 · 页面根/背景全屏 · 底栏铺满 · 标题贴顶 · 顶区对齐 · 卡牌网格左上 · 竖向列表撑高/Clamped/顶部对齐 · 面板式弹窗豁免)。 剩下的是视觉/间距/字号/美术位置微调(规则⑤明确留给负责人)与你在 Play 里具体点出的某页错位。
- 建议后续方式:不要再泛查 —— 你指具体页面 + 截图,我按同一套方法做定点修正(每批留证据 + 编译/自检 + 你复验)。
- 验证:本轮无场景/代码改动(纯核对);编译与自检保持上一轮状态(96/0)。
- 新增
- 第 87 轮 · UI 适配开工:逐页布局核查(21 页)+ 首批 2 处修复
- 新增
Logs/ui-adapt-audit.ps1(只读、纯 ASCII)→Logs/ui-adapt-audit.md:逐页核对 9 条锚点规则 (根/背景全屏 · 底栏横向铺满 · 列表childAlignment是否 MiddleCenter ·ContentSizeFitter.verticalFit是否 Unconstrained),并豁免面板式弹窗(规则⑧)。 - 核查结果(21 页):绝大多数 OK;真问题 2 处:
① 🔴
Pending shipmentCanvas底栏没横向铺满(违反规则③)⇒ 不同宽高比设备上底栏宽窄不一; ② 🔴MailPage邮件有 2 个列表容器是 Unconstrained ⇒ 我上轮接入滚动修复时漏了邮箱页。 另 3 处(Product Purchase Interface/Purchase Success Page/联系客服Page背景"非全屏")是我判据的误报 —— 它们是面板式弹窗,背景不平铺正是负责人确认过的正确做法(规则⑧)。 - 修复:① 工具新增
NormalizePendingShipmentBar()(只改水平锚点与 offset,高度/竖直位置不变 ⇒ 不跳位)并在步骤里调用; ②ClientMailPage.Show()接入ClientScrollFix.FixAll✓ - 验证:编译三目标 0 error;
Logs/repair-adapt1.log显示底栏已铺满;自检 96 项 / 失败 0(退出码 0)✓; 审计复跑后Pending shipmentCanvas由 ✘ 变 OK(bar=stretched) ✓ ⚠️ 审计读的是场景文件:邮箱页仍显示unfit=2,那是场景里的作者值,运行时已由ClientScrollFix修正 ✓(不是遗漏)。- 下一步(逐页适配继续):按同一脚本逐页核对剩余规则(标题贴顶 / 顶区对齐 / 网格左上 / 面板式弹窗豁免), 发现问题即用工具做机械性锚点修正(改锚点按世界坐标回写、不跳位),每批后由负责人 Play 复验。
- 新增
- 第 86 轮 ·
BUG-025方案 C 落地 + 冗余阵容卡已清理 + 全量自检 96/0(首次跑通)- ①
BUG-025方案 C 已落地 ✓:新增客户端专用启动场景Assets/Client/Scenes/ClientBoot.unity(对象ClientBoot+ClientBootLoader,职责仅Start()→LoadScene("ClientShell")), 并置首。实测构建顺序ClientBoot → Boot → ClientShell(原Boot.unity保留未动,可随时调整顺序回滚)。 证据:Logs/repair-clientboot.log的构建场景顺序(前 5 个):ClientBoot → Boot → ClientShell+ProjectSettings/EditorBuildSettings.asset✓ ⇒ 移植侧硬阻断解除(导出的包现在能进到客户端 UI)。 - ② 冗余阵容卡已清理 ✓:工具
RemoveRedundantLineupCards()删除了我上一轮新建的容器(含 3 张展示卡牌); 自检诊断确认阵容弹窗内现在恰好是场景既有的 6 张角色卡牌Button-final✓(干净)。 ⚠️ 过程中的自我更正:第一版清理没生效,因为它是沿玩家阵容/Content路径查找、任一环没命中就静默 return(无日志) ✗。 改为"在弹窗内找全部子节点名都是展示卡牌的Content"并每步打日志后才成功 ✓(教训:工具里的提前 return 必须留痕,否则"没做"和"做了但没事可做"分不清)。- ③ 自检首次跑通:96 项 / 失败 0,退出码 0 ✓(
Logs/self-test.log)。 同时修掉自检里过时的期望:收藏品可见条数已按负责人决定(B)由1/1/1/3/1变为6/6/5/9/9,断言同步更新 ✓ - 备份:
Logs/ClientShell.before-clientboot.unity.bak、Logs/ClientShell.before-cleanup2.unity.bak。 - 下一步(等负责人):① 按上表命名导出贴图 ⇒ 我接线收藏品/排行榜图标 ② UI 适配(建议单独立项,先出全页问题清单)。
- ①
- 第 85 轮 ·
BUG-025选方案 C + 清理冗余阵容卡:代码与工具已就绪,待关编辑器执行场景写入- 负责人决策:
BUG-025→ 方案 C(新建只做客户端初始化的ClientBoot场景并置首);清理上一轮我新建的 3 张冗余阵容卡。 - 已写好(编译三目标 0 error ✓):
· 新增
Assets/Client/Runtime/ClientBootLoader.cs—— 职责极小:Start()里SceneManager.LoadScene("ClientShell")(客户端数据由ClientShell内的ClientBootstrap初始化);不改动原Boot场景,只新增入口场景并置首,可随时从构建清单移除回滚。 · 工具新增EnsureClientBootScene():场景不存在则新建(空场景 +ClientBoot对象 +ClientBootLoader)并保存;把ClientBoot放进EditorBuildSettings第 0 位;确保ClientShell在清单中;不删不动原Boot.unity条目;日志打印前 5 个场景顺序。幂等。 · 工具新增RemoveRedundantLineupCards():删除Player lineup/玩家阵容/Content(我上轮新建的容器 + 3 张展示卡牌); 安全护栏:只有当该容器全部子节点名都以展示卡牌开头时才删 —— 场景既有 6 张角色卡牌Button-final在别处、不受影响(代码两种名字都收)。幂等。 - ⏸ 未执行:Unity 编辑器正在运行(跑批处理必须先关它,否则会打断你的操作)⇒ 请关掉编辑器后说一声,我立刻执行
① 新建
ClientBoot场景并置首 ② 删除冗余阵容卡 ③ 复核构建清单顺序 + 跑全量自检(96 项)。 - 备份策略:执行前会备份
ClientShell.unity(Logs/ClientShell.before-clientboot.unity.bak)。
- 负责人决策:
- 第 84 轮 · 落实负责人第二批决策(个性化交互 + 演示数据 + 其余页滚动修复 + 缺图清单)
- 负责人决策与落地:
· 个性化"演示效果"选 B ⇒ 已把
Head/HeadFrame/Badge/Nameplate/Title五张表全部行改为ClientShow: 1(6/9/6/5/9 = 35 行)⇒ 列表可见条数由1/1/1/3/1变为 6/9/6/5/9,未拥有的显示"未解锁"态 ✓ · 个性化「确定键」语义(负责人原话:点条目选中后再点确定键进行替换,而不是返回)⇒ClientProfilePage改为 点条目=只选中(高亮 + Toast「已选择…(点确定键替换)」),5 个子界面的个性化确定键Button(Content_Avatar/Frame/Info/Title/Widget)绑定为确认替换; 未选中时提示"请先选择…";旧的"点击即装备"入口保留为兼容转发 ✓ · 其余列表页接入滚动修复 ⇒ 已接入 英雄 / 商店 / 活动 / 主页展示 / 全图鉴活动 / 英雄详情(各自Show调用ClientScrollFix.FixAll)✓ · 装备(不管数据、有接口就行)· 战力(显示哪个都行)⇒ 不动 ✓;邮件 ⇒ 已结 ✓;未接入页面不做 ⇒ 不再提议 ✓ · 清理我新建的 3 张冗余阵容卡 ⇒ ⏸ 需先关掉你的 Unity 编辑器才能跑批处理删除;仅视觉冗余、当前被隐藏,不清也无功能影响 ✓ - 缺图清单已产出(写入
BUG_TRACKER.md,负责人已同意提供素材):工程内按命名规范的贴图实测全为 0 (HeroAvatar*/AvatarFrame*/Medal*/Nameplate*/Title_*/AttributeIcon*/Item_*); 而Assets/Client/UI/切图(11)/**有中文名原始切图(头像 30 / 头像框 11 / 徽章 7 / 铭牌 14 / 称号 14)。 需要"id ↔ 贴图"的对应(按规则命名导出,或给我一份对照表);另有Head表ResId字段为空、元素 6(暗)缺图、 属性图标 0 张、排行榜条目AvatarId/FrameId/BadgeId全为 0(数据侧) 三处已在清单中标注 ✓ - 验证:编译三目标 0 error ✓(新增/改动的页面均已纳入);自检仍待补跑(你的编辑器占用中)。
- 负责人决策与落地:
· 个性化"演示效果"选 B ⇒ 已把
- 第 83 轮 · 更正上一轮修复的副作用:排行榜整列右移(我只改了竖直方向)
- 负责人复验:编队/个人中心等其它都通过 ✓;但排行榜所有行整体右移、右边缘被裁掉、左半空着(附截图)。
- 根因是我的第一版修复:把容器的水平也改成拉伸(
anchorMin.x=0/anchorMax.x=1)⇒ 容器宽 = "视口宽 + 作者设定的sizeDelta.x" ⇒ 远比原本宽 ⇒ 网格居中排布后整列右移并被 Viewport 裁切。 - 修法:
ClientScrollFix改为只调竖直方向 ——anchorMin/anchorMax/pivot的 x 一律沿用作者值; 对齐只改竖直分量,水平分量保留(TextAnchor编码0..2 = Upper*、3..5 = Middle*、6..8 = Lower*⇒(int)value % 3即水平分量)。 - 教训(已写入 BUG-027):修布局问题时只改与问题相关的轴;"看起来更标准"的通用写法在作者已调好宽度的页面上会变成副作用 —— 最小改动优先。
- 验证:编译三目标 0 error ✓;视觉结果待负责人 Play 复验(我不能代替 GUI 验证)。
- 自检仍未跑(你的编辑器占用中)。其余列表页(英雄/商店/邮箱/活动)仍未接入该修复,等你一句话。
- 第 82 轮 · 滚动列表根因修复(排行榜/编队"只显示 6 条 + 松手弹回 + 默认不在最上面")
- 负责人复验:客服弹窗 ✅ 通过、邮箱 ✅ 通过;排行榜仍不行(只显示 6 个、下滑松手被拉回、默认不在最上面),编队 Scroll View 同样; 并推测"估计是 middle center 导致的" —— 推测正确。
- 场景实测根因(三条叠加,全都是配置而非逻辑):
①
ContentSizeFitter.m_VerticalFit: 0(Unconstrained)⇒ 内容不撑高 ⇒ 只显示作者高度那几条,且内容高≈视口高 ⇒ 滚动范围为 0 ⇒ 一滑就回弹; ②ScrollRect.m_MovementType: 1(Elastic)⇒ 松手弹回; ③GridLayoutGroup.m_ChildAlignment: 4(MiddleCenter)⇒ 内容居中 ⇒ 默认看中间而非顶部。 - 新增
Assets/Client/Runtime/UI/ClientScrollFix.cs(运行时修正,不写场景/不动美术): 撑高(verticalFit = PreferredSize)+movementType = Clamped+childAlignment = UpperCenter+ 容器顶部锚点/轴心 + 重排后回到顶部; 只处理竖向列表(vertical && !horizontal)。 - 已接入:
ClientRankPage.Show()(两个榜)、ClientFormationPage.Show()、ClientProfilePage.Show()。 - 未接入(等你确认):英雄 / 商店 / 邮箱 / 活动 等其余列表页大概率同样有问题;工具已备好,接入只是一行调用,为避免复验期引入额外变化先不动。
- 验证:编译三目标 0 error(新增文件已纳入两个 profile)。
⚠️ 自检仍未跑(你的编辑器占用中,跑批处理必须先关它)。
- 第 81 轮 · 负责人首轮验收反馈:3 项逻辑问题已修 + 1 项说明(个性化"删改")+ UI 错位暂缓
- 负责人结论:大部分逻辑与功能没问题;UI 错位/不适配属意料之中,后续专门改、现在不用管(已记为暂缓项,本轮未做任何排版改动)。
- ① 客服会话界面点"确定键"或空白处都返回不了上一级 ✅ 已修(两条根因):
· 遮罩只被显隐、没有任何点击处理 ⇒ 点空白无反应 —— 这是所有弹窗的共同问题(不只客服页);
已在
ClientPopupService.EnsureMaskClickClosesTop()运行时给遮罩补Button(transition=None,不改尺寸/排版)→ 点击CloseTop(); · 客服弹窗内没有任何关闭键绑定 ⇒ClientHomePage.BindContactPopupClose()按常见命名(确定键Button/确定Button/确定/关闭键Button/关闭Button/退出Button)查找并绑定,找不到只记日志;另把background/底框绑为"点空白关闭"兜底。 - ② 排行榜只显示前 5 名,要求前 50 名 ✅ 已修:根因是模拟数据每榜只有 5 条 ⇒
LocalClientDataService.BuildLeaderboard(50, …)补足到 50 条(前 5 名保留原样例,其余确定性规则、不用随机数,便于复现与自检);ClientRankPage新增"行容器 + 首行模板",EnsureRankRows()运行时克隆补足,上限 50(不写场景)。 - ③ 邮件"全部删除" ✅ 已修(按负责人给的规则"全部领取和已读后才能删,删完显示暂无邮件"):
新增
IClientDataService.TryDeleteAllMails()—— 逐封校验已读+已领取,不满足即拒绝并说明原因;通过则清空 +DataChanged;ClientMailPage.DeleteAll()+ 绑定 —— 场景里删除键在Panel/All delete/Button下、按钮节点本身叫Button(名字太通用)⇒ 按父节点All delete取子 Button(BindButtonUnder),避免误绑; 删完Refresh()走既有空态 ⇒Default/No emails+ "暂无邮件" ✓(场景本来就有该节点)。 - ④ 解释(非缺陷):个性化页签 5 个子界面"被删改" —— 是我做过的列表收敛(证据
Logs/repair-profilelists.log53 处变更): 删掉每列预摆的演示项、把模板改名为xxxItem并禁用(仅作克隆源),运行时按数据生成;原因是表按ClientShow过滤后可见条数为 1/1/1/3/1, 不收敛就会出现"数据 1 条、界面 5 个假条目"。代价:默认演示效果不见了。三个方向待你定(A 保持数据驱动 / B 打开表中更多ClientShow行或补模拟数据让界面自动变多 / C 恢复内联演示项,不推荐)。 - 验证:编译三目标 0 error ✓。
⚠️ 自检本轮未跑:你的 Unity 编辑器处于打开状态,跑批处理必须先关掉它 ⇒ 为避免打断你的验收,我没有执行;等你关掉编辑器我再补跑(或你直接 Play 复验这三处)。 - 详见
BUG_TRACKER.mdBUG-027。
- 第 80 轮 · 射线可达性审计(只读):169 个按钮中 4 个无法静态判定,均为 prefab 实例(无真缺口)
- 新增
Logs/ui-raycast-audit.ps1(只读、纯 ASCII)→ 报告Logs/ui-raycast-audit.md。 这轮查的是"看着在、点不到"的另一种机制:按钮子树的图是否接收射线(m_RaycastTarget),以及祖先CanvasGroup.blocksRaycasts是否被关。 - 判据:按钮可点 ⇔ 其场景可见子树里至少有一个
m_RaycastTarget=1的 Graphic(射线命中后向最近的 Button 祖先冒泡);或有祖先CanvasGroup.m_BlocksRaycasts=0则直接不可点。 - 结果:169 个按钮 → 4 个候选,且 4 个的路径全为空 ⇒ 它们正是 prefab 实例根(实例根的 Transform 在场景 YAML 里是 stripped 的,静态解析取不到路径)—— 属已知假阳性类别,没有可执行发现;其余 165 个按钮的子树的都有可接收射线的图 ✓
- 本轮我自己踩的坑(都在工具里,已修):① 拿 6 位 guid 前缀去比 32 位全 guid ⇒
buttons = 0(静默"零发现",最容易误判成"没问题"); ② 子树遍历遇到 prefab 实例根的无 Transform ⇒ 键为 null 抛异常,已加保护;③CanvasGroup改为按字段特征(m_BlocksRaycasts)识别,不再依赖 guid(它来自内置模块、不在包缓存里)。 ⇒ 教训同前:"0 发现"必须先确认工具真的在工作(本轮靠"按钮数=0 与 169 矛盾"发现)。 - 本轮无任何场景/代码改动(验收期间冻结)。
- 审计工具矩阵已达 7 个(均只读、可重跑):接线 / 节点契约 / 类型一致性 / 返回关闭闭环 / 死按钮 / 分层排版 / 射线可达。
- 下一轮(第 24 轮,本目标最后一轮)建议:若无新指令,不再新增边际审计,改为收尾——汇总七份审计结论与待办、刷新
CURRENT_STATE/MODULE/看板,等你验收结果。
- 新增
- 第 79 轮 · UI 分层与列表排版核对(只读,验收期间不改动)
- 新增
Logs/ui-layout-audit.ps1(纯 ASCII,只读)→ 报告Logs/ui-layout-audit.md,三段:①ClientCanvas子层与激活态;② 19 个已登记节点的实际父层 / 是否全屏;③ 全部列表容器(Content)的布局组件。 - 结论:分层与排版均无异常 ✓
·
ClientCanvas子层:PopupLayer[1]/PagesLayer[1]/SystemLayer[0]/ToastRoot[0]—— 唯一异常仍是已知的SystemLayer常驻 inactive(RISK-020待你选 A/B/C); · 19/19 已登记节点都在PopupLayer✓(PagesLayer只放MainPage主页,与既有结论一致); · 页面根形态:12 个全屏、7 个面板型(Exchange code interface/Historical Order Interface/Pending shipmentCanvas/Player lineup/Product Purchase Interface/联系客服Page等)—— 与你此前判定"Player lineup是面板型、不该全屏拉伸"一致 ✓,不是缺陷; · 31 个列表容器全部具备GridLayoutGroup+ContentSizeFitter✓(0 个缺布局组件)⇒ 列表克隆/排版前提齐备。 - 本轮无任何场景/代码改动(验收期间刻意冻结;跑批处理会关掉你的编辑器、改代码会触发重编译并打断 Play)。
- 等你验收:清单
UI_ACCEPTANCE_CHECKLIST.md(A~G 七组)。验收通过后我再做排队项(清理我新建的 3 张阵容卡 → 落地你确认的产品项)。
- 新增
- 第 78 轮 · 阵容卡根因修复 + 场景接线回归自检 + 交付验收清单(负责人正在验收)
⚠️ 本轮起暂停一切场景写入与代码改动 —— 负责人已开始人工验收;场景写入会让 Unity 重载、代码改动会触发重编译并打断 Play。 后续改动等验收结果再排(已排队项见下)。- 🔴 阵容弹窗根因(比原先判断更深):
ClientRankPage.CollectLineupCards()原先只查第一个Content、且只认展示卡牌前缀 —— 而实测阵容弹窗里本来就有 6 张角色卡牌Button-final(既有列表)⇒ 一张都没被收集(弹窗只有层数/回合数/战力)。 修法(代码):在整个阵容弹窗内按名收集,两种前缀都收;并排除名字含Scroll的容器 —— 因为场景里的滚动容器就叫展示卡牌Scroll View(同以前缀开头),若把它当成一张卡,Refresh(null)会SetActive(false)把整个卡牌区关掉。 - 自检新增"场景接线回归"(
ClientSelfTest.RunSceneWiringChecks):批处理里只读打开ClientShell.unity(不保存), 用SerializedObject断言关键引用与节点:弹窗遮罩、邮件红点、ProfilePage 五类收藏品模板+容器+主页展示、改名链路三按钮节点、 阵容弹窗卡牌与关闭按钮、邮箱一键按钮、BottomFunctionIconView._icon全部接线。 ⇒ 以后场景/工具被改坏,自检会直接以非 0 退出码报出来,不必等你 Play 才发现。 ⚠️ 自检自身踩的两个坑(已修):① 用GameObject.Find找节点 —— 它只返回激活对象,而弹窗默认隐藏 ⇒ 误报"节点不存在",已改为根节点深搜(含未激活); ② 断言"阵容卡数"时把展示卡牌Scroll View也算成卡 ⇒ 已与代码同一判据(排除Scroll;卡 =角色卡牌Button*或展示卡牌+数字)。- 最终自检:96 项 / 失败 0(
Logs/self-test3.log);编译三目标 0 error; 诊断输出确认阵容弹窗内卡牌节点 = 9 个(既有角色卡牌Button-final×6 + 本轮新建展示卡牌1..3)。 - 交付
UI_ACCEPTANCE_CHECKLIST.md(A~G 七组、每项含步骤/预期/失败回传;含"已知未完成/待决定"与自动基线;附复现命令与"跑批处理前必须先关编辑器"的提醒)。 - 已排队的改动(等验收后再做):
- 清理候选:本轮新建的
展示卡牌1..3与既有 6 张重复 —— 若 E2/E4 显示正常,则删掉我新建的 3 张(已记入BUG_TRACKER待核验清理项,含回滚方式); - E 组若不过,按你回传的 Console/截图定位(阵容卡的等级/星级/立绘走
等级-Text回退与既有贴图表); - 你确认后落地
个性化确定键语义、SystemLayerA/B/C、邮件正文 A/B/C 等。
- 清理候选:本轮新建的
- 第 77 轮 · 死按钮审计:抓到 5 处"点了没反应"(4 处已修)+ 修掉一个静默失败根因
- 新增
Logs/ui-dead-buttons.ps1(纯 ASCII,可重跑)→ 报告Logs/ui-dead-buttons.md。 判据:场景Button既没有场景持久事件(m_MethodName),其名字又没出现在任何运行时代码的绑定/查找行里。 - 实测:场景 169 个按钮,其中 0 个走场景持久事件(全场景仅 3 个
SetActive持久调用且不在按钮上 —— 按钮一律由代码绑定,符合本工程架构);首轮候选 67 个,复核后确认 5 处真缺口:按钮 问题 处置 Panel_Profile/底框/改名称改名入口点不开 ✅ 已修(绑定 OpenRenameDialog)RenameDialog/ConfirmButton确认改名没反应 ✅ 已修(绑定 ConfirmRename)RenameDialog/CancelButton取消没反应 ✅ 已修(绑定 CancelRename)MailPage/Email come/Panel/All read/All read button一键领取附件没反应 ✅ 已修(绑定 ClaimAll)个性化确定键Button×6个性化各分类"确定"无绑定 ⏸ 保留待确认(本实现是"点条目即装备","确定键"的语义属产品规则,不臆造) - 🔧 修掉静默失败根因:
ClientProfilePage.BindButton原先用transform.Find(只查直接子级), 而改名称在Panel_Profile/底框/下、确认/取消在Panel_Profile/RenameDialog/下 ⇒ 一个都找不到且不报错。已改为深搜(FindDeep),与其它页面一致 ✓ClientMailPage同样新增深搜绑定(含找不到时的明确告警,不再静默)。 - 不臆造行为(仅记录):邮箱
All delete(IClientDataService没有删除/批量已读接口 ⇒ 未实现功能);元素筛选按钮(你此前明确本阶段不做);未接入页面内的按钮。 - 审计工具的假阳性来源(已写入文档):看不到"用序列化字段接的按钮"(
_leftButton/_rightButton/_equipmentButtons/_heroTabButton/_addButton等)⇒ 这些会误报。 - 验证:编译三目标 0 error;修复后重跑审计,4 个按钮已从候选中消失(67 → 63);自检 70 项 / 失败 0、退出码 0 ✓
- 已写入
MODULE.md §18.3;本轮无场景写入(改动全在代码层)。 - 建议 Play 复核:个人中心点
改名称→ 输入框弹出 →确认应生效(名称更新 + Toast)、取消应关闭;邮箱页点一键→ 附件入包 + Toast。
- 新增
- 第 76 轮 ·
BUG-026全部处置完毕(负责人"全部授权"+"允许在合适的位置新建")- ① 弹窗遮罩/输入阻断 ✅ —— 关键发现:工具里的
EnsurePopupMask()早就写好了却从未被调用(所以场景里一直没有遮罩节点)。 本轮补上调用 ⇒ 新建ClientCanvas/PopupLayer/弹窗遮罩(全屏 +raycastTarget、默认隐藏,由ClientPopupService.ApplyMask动态维护)+ 接线_maskRoot✓ - ② 邮件红点 ✅ —— 克隆现成
ActivityButton/RedDot→CanvasBottomFunction0/BottomFunctionIcon_Mail/RedDot(默认隐藏)+ 接线_mailDot✓ - ③ 页面提示 ✅(两种情形都查清了):
·
ClientHomePage本来就已把提示发给全局 Toast ⇒ 我此前把它列为"真缺口"是误报(已更正); ·ClientProfilePage确实没有 ⇒ 本轮让它实现IClientFeedbackHost+BindFeedback,ShowNotice优先走全局 Toast(_notice仅作兼容回退)✓ - ④ 底栏图标/文字 ✅(一半)——
BottomFunctionIconView._icon已接(Bottom1..4/Image);_label无对应节点(这些节点只有一个Image子节点、没有文字,且Configure无调用方)⇒ 如实记录,不臆造文字节点 ✓ - ⑤ 排行榜阵容卡 ✅ —— 在
Player lineup/玩家阵容下新建Content(GridLayoutGroup 3 列)+ 3 个共用卡 prefab 实例展示卡牌1..3(保留 prefab 关联); 该 prefab 已含卡牌名称/等级-Text/立绘Image/品质Image/品质底框Image/属性图标Image/星级图标Image (1..5)⇒ 正好覆盖LineupCardRow所需 ✓ - ⑥ 阵容弹窗关闭 ✅ ——
Player lineup右上角新建关闭Button(克隆自排行榜返回按钮),ClientRankPage.OpenLineup()绑定CloseLineup✓ ⚠️ 又更正我一处审计误报:我说"星级图标Image (1..5)工程内不存在"是错的 —— 共用卡 prefab 本来就有; 误报原因是代码里写的是前缀字面量"星级图标Image (" + i + ")",而我的比对当时只做全名相等。 已修审计判据(字面量是任一节点名的前缀即算命中)⇒ A 类清单随即变干净 ✓- 最终审计状态:A 类无未处理真缺口(只剩编辑器工具的字符串片段、以及已有兜底的
前往获取*与已加回退的LV等级); B 类 39 条全部为已解释的非缺口。 - 验证:编译三目标 0 error;
repair-bug026a.log(37 处变更)/repair-bug026b.log(43 处变更)均error CS 0、异常 0; 自检 70 项 / 失败 0;场景复核_maskRoot/_mailDot/_icon非 0,弹窗遮罩、BottomFunctionIcon_Mail/RedDot(均active=false)、玩家阵容/Content、关闭Button均存在 ✓ - 备份:
ClientShell.before-bug026a.unity.bak、ClientShell.before-bug026b.unity.bak;Unity 已开回。 - 建议你 Play 验收:① 打开任一弹窗看遮罩是否挡住下层点击;② 大厅邮件入口是否出现红点(有未读/未领邮件时); ③ 个人中心点未拥有的收藏品 → 应弹 Toast 提示;④ 排行榜点"查看" → 阵容弹窗应有 3 张卡 + 右上角关闭按钮。
- ① 弹窗遮罩/输入阻断 ✅ —— 关键发现:工具里的
- 第 75 轮 · 页面/弹窗「返回·关闭闭环」核对:闭环基本完整,另发现阵容弹窗无关闭手段
- 新增
Logs/ui-flow-matrix.ps1(纯 ASCII,中文关键词用字符码构造)→ 报告Logs/ui-flow-matrix.md: 对 19 个已登记场景节点列出pageId/ 代码引用数 / 是否需要返回·关闭节点。 - 结论:返回闭环基本完整 ✓ —— 各页返回都绑在
BackoffButton(不是后退Button),且场景里各页都有该节点: 排行榜ClientRankPage:80、活动页ClientActivityPage:298/302、商店ClientShopPage:401、全图鉴活动ClientCompleteGuideEventPage:345-347✓; 英雄/英雄详情/编队/邮件/个人中心 走后退Button(工具BackButtonPaths5 条)✓;Purchase Success Page点空白关闭 ✓。 - 🔴 新发现:
Player lineup(玩家阵容)子树里没有任何按钮 ⇒ 打开后关不掉 —— 与它"没有卡牌节点"同源,该弹窗整体未完成。 已并入BUG-026缺口清单(新增第 6 项)。 ⚠️ 我又踩了同一个坑(第 3 次):脚本里写了中文字面量'后退'/'关闭',被 PowerShell 按 ANSI 读成乱码 ⇒ 关键词永远匹配不上, 导致首轮结果"所有页面 back=False"与已知事实矛盾(ProfilePage个人中心/后退Button明明存在)。改为字符码构造[char]0x540E+[char]0x9000后结果正确 ✓ ⇒ 结论:.ps1里一律不得出现非 ASCII 字面量;需要中文就用字符码或从文件读。- 审计工具的已知判据盲区(已写入 BUG-026,避免误读):只认
后退/关闭/Backoff,不覆盖取消键Button这类业务命名 (例:Product Purchase Interface实际由取消键Button关闭,ClientShopPage:285);prefab 实例内部节点不在场景 YAML 中,可能漏判。 - 本轮无代码/场景改动(纯静态核对 + 工具)⇒ 无需重新编译。
- 待授权仍未回复:
BUG-026的 6 项缺口(弹窗遮罩、邮件/公告红点、页面提示、底栏图标文字、排行榜阵容卡、阵容弹窗关闭手段)。
- 新增
- 第 74 轮 · UI 类型一致性审计:127 处引用 0 不符(含阳性对照)
- 新增
Logs/ui-type-audit.ps1(纯 ASCII,可重跑) → 报告Logs/ui-type-audit.md。 这轮查的是比"有没有接线"更隐蔽的一类:字段声明类型与它引用的场景组件实际类型不一致 ——AGENTS.md§4 明令"文本必须按场景真实组件类型声明",不一致会让引用静默失效(BUG-018的成因)。 - 判据:解析客户端每个序列化字段的声明类型(
Text/TMP_Text/Image…), 再解析场景里该字段指向的组件 guid(f4688f…=TMP、5f7201…=旧版 UGUI Text、fe87c0…=Image、4e29b1…=Button)后比对。 - 结果:解析到 107 个声明字段、比对 127 处非空引用 ⇒ 0 处不符 ✓
⇒ 结论:「文本类型声明与场景不符」这一类只在
BUG-018出现过一次,且已修复;其余全部正确。 - ✅ 阳性对照(确认审计不是"0 因为没比较"):同一次运行解析出的被引用组件种类分布为
class1(GameObject) 49、TMP_Text22、Transform17、Image17、Button12、UGUI_Text8、其它 2 —— 两类文本都在场,若真有错配必然会被捕获 ✓ - 已写入
MODULE.md §18.2(工具与判据);本轮无代码/场景改动 ⇒ 无需重新编译。 - 仍待授权(
BUG-026的 5 项真缺口):弹窗遮罩_maskRoot、邮件/公告红点、页面提示_notice、底栏BottomFunctionIconView._icon/_label(以上都只需指向现成节点)、排行榜阵容卡(需新建或改为不显示)。 - 下一步(不写场景也能做):继续逐页做契约与健壮性核对;等你授权后再统一接线。
- 新增
- 第 73 轮 · UI-only 重启:UI 契约审计系统化(脚本 + 报告)+ 修掉一处潜伏空引用
- 范围:负责人 2026-09-21 明确 "该任务只负责UI" ⇒ 目标已改为 UI-only(平台移植/WebGL/真机/
BUG-009·013·025不在本任务)。 - 把
MODULE.md §18的核对法做成可重跑脚本:新增Logs/ui-contract-audit.ps1(纯 ASCII,避免.ps1被按 ANSI 读坏的旧坑)→ 报告Logs/ui-contract-audit.md。 两条判据:A 代码里"按名查找"的字面量在**场景 + 全部 prefab(920 个名字)**中都不存在;B 场景里客户端组件的序列化字段为fileID 0。 结果:A 类真命中 1 处、B 类 40 条(分类见下)。已记BUG-026。 - A 类真缺口(1 处):排行榜"查看阵容"弹窗没有卡牌节点 ——
ClientRankPage找展示卡牌*及子节点卡牌名称/LV等级/星级图标Image (1..5), 在全部 498 个 prefab/场景/asset 里 0 命中 ⇒ 弹窗只有层数/回合数/战力,没有卡牌。 ✅ 已核实不会崩:OpenLineup按_lineupCards.Count循环,列表空即空转。 - B 类分类(40 条):真缺口 5 项 —— ①
ClientPopupService._maskRoot(弹窗无遮罩/无输入阻断) ②ClientHomeRedDotController._mailDot/_noticeDot(邮件/公告红点不显示;活动红点已接 ✓) ③ClientHomePage._notice/ClientProfilePage._notice(提示文本静默不显示,ClientHomePage.cs:217已有取证注释) ④BottomFunctionIconView._icon/_label×4(底栏图标/文字,目前无调用方) ⑤ 排行榜阵容卡(同 A 类)。 其余全部判定为非缺口(有兜底或本就可选):ClientUiPopup._popupRoot×18 回退gameObject、ClientShellController._popupService/_feedback走GetComponentInChildren、ClientHeroPage._heroTabSelected/_guideTabSelected代码注明可选、ClientHeroCard._teamBadgeNumber仅编队用、ClientSystemFeedback._toastText是旧版遗留(TMP 的_toastLabel已接)、ClientMailPage._emptyHint运行时自补、BUG-020的两个文本字段刻意留空、BUG-019四张表缺美术。 - ✅ 本轮代码修复 1 处(潜伏崩溃):
BottomFunctionIconView.Configure原先没有判空,而Bottom1..Bottom4的_icon/_label都是fileID 0⇒ 一旦有人调用就空引用抛异常。已改为逐项判空(未接线即跳过),语义不变。 另核实ClientHomeRedDotController.SetVisible有判空 ⇒ 红点只是"不显示",不会崩。 - 证据:编译三目标 0 error;审计脚本可重跑(
Logs/ui-contract-audit.ps1→.md)。 - 待授权(
AGENTS.md§4:不擅自写场景):上述真缺口 1~5 项,全部用现成节点接线即可(唯 ⑤ 需新建或改为不显示); 其中 ① 遮罩、② 红点、③ 提示 属于交互稿明确要求的可见行为,建议优先。 - 下一步:等负责人授权场景写入(或给出"不做"的取舍);期间可继续做不写场景的 UI 代码健壮性与契约核对。
- 范围:负责人 2026-09-21 明确 "该任务只负责UI" ⇒ 目标已改为 UI-only(平台移植/WebGL/真机/
- 第 72 轮 · 流程文档同步(AGENTS.md §5/§6 的强制项)+ 消除两处与实况冲突的旧约束
DEVELOPMENT_WORKFLOW.md(88 → 162 行): ·⚠️ 更正一处与实况冲突的强制约束:原文写"所有可导航页面必须位于PagesLayer,弹窗在PopupLayer,提示/遮罩/加载在SystemLayer", 但实测:PagesLayer只有MainPage主页,其余客户端页面(英雄/编队/个人中心/商店/邮件/排行/活动…)都在PopupLayer;SystemLayer恒 inactive、Toast 挂在ClientCanvas下 ⇒ 已标注"在RISK-020定案前,本行不再作为强制约束"。 · 更正目录树:原文有Assets/Client/Tests/,实测不存在;已改为Editor/(含自检套件),并说明"不能直接用 UTF 的 asmdef 原因 + 改 asmdef 属架构变更需授权"。 · 新增## 2026-09-20 客户端阶段状态与决策记录(AGENTS.md §5 要求的阶段状态 + 决策记录): ① 本会话已完成项(8 项,各带证据文件);② 未完成/阻断;③ 负责人决策记录 7 条; ④ 待拍板 6 项;⑤ 三条命令行验证入口。PROJECT_OVERVIEW.md:Assets/Client的状态从"C0 进行中"改为**"已表驱动"(10 张表、收口完成、自检 70 项通过); 并在"启动与资源链路(已核验)"补上与BUG-025一致的结论**:该链路只到LoginScene,ClientShell既不在构建设置也无人加载 ⇒ 现状构建的 WebGL 包进不到客户端 UI,三方案待选(指向WEBGL_B0_GATE.md)。- 证据:纯文档改动 ⇒ 按
AGENTS.md§3 只做文本核对(行数/章节/关键词已复查); 确认DEVELOPMENT_WORKFLOW.md里已无"PagesLayer 强制约束"的现行冲突残留(只剩更正说明里引用的原文)。 - 结论:桌面侧已无任何可推进项 —— 目标剩余部分(阶段 B 全部、阶段 A 的 3 处定向决策)必须由负责人输入。
- 第 71 轮 · 客户端纯逻辑自检套件落地(阶段 A3「自动化测试」缺口关闭):70 项全通过
- 新增
Assets/Client/Editor/ClientSelfTest.cs(菜单Client/自检/运行全部纯逻辑自检;命令行入口ClientSelfTest.RunAll)。 - 先讲一个约束(决定了做法):
Assets/Client没有 asmdef ⇒ 代码在预定义程序集Assembly-CSharp; 而 asmdef 测试程序集无法引用预定义程序集 ⇒ 不能直接用 Unity Test Framework(除非把客户端整体改成 asmdef = 架构变更,需你授权)。 因此采用 Editor 自检 + 命令行退出码:任一断言失败即以非 0 退出,可直接进构建前门禁 / CI。 - 覆盖 70 项断言(均为高风险纯逻辑):表加载(英雄可见 49 / 道具 9)、元素映射(1..6 ↔ 光水土风火暗 + 越界不抛)、
道具类型映射(表
Type只允许 1/3;背包项ItemType必须等于表Type的映射;**并真的走一遍"一键领取"**再校验)、 说明文本格式化(1→8%、15→9%、20→80%、无分档原样返回)、能力页签归属(页签名/主技能名/条数 12·1·0 + 守恒式:各页签条数之和 = 该英雄天赋表行数 13 ⇒ 无漏归属)、收藏品可见数(1/1/1/3/1= ProfilePage 验收基准)、 远端 pkg 读取链(自建"3 行 Hero"的 pkg → 断言路径变远端且可见英雄 = 1 → 自删并复位)。 - ★ 把上一轮手工做的"变异 pkg 验证"变成了自动化回归:日志实测三行
本地 Resources/Table…Hero 可用 49 / 表内 54→远端落盘包 config.pkg(1 张表);Hero 可用 1 / 表内 3→本地 …49 / 表内 54✓ 且安全:若persistentDataPath/config.pkg已存在,该项自检直接跳过,绝不覆盖你的数据。 - 证据:编译三目标 0 error;
Logs/self-test.log——error CS 0/ 异常 0 /通过 70 项 / 失败 0 项、退出码 0。 ⚠️ 首次运行 57 通过 / 6 失败,6 项全是我自己写错的期望值(把DisplayName当成主技能名、把英雄天赋表总行数当成各页签条数)。 修正后全通过 —— 这正是自检的价值:它先抓住了写测试的人。留档Logs/self-test.first-run.log作对比。⚠️ 再次遇到 PowerShell 输出管线故障(out-lineoutput异常,本次变体是FormatEntryData ... not in the correct sequence), 导致一次 Unity 批处理看起来跑了其实没跑(日志时间戳新但内容是旧的)⇒ 我改成"先移走旧日志再跑"来消除歧义 ✓ 已记入文档。- 顺带确认(来自自检日志的
数据源行):收藏品可见/表内 = 头像1/6、头像框3/9、徽章1/6、铭牌1/5、称号1/9✓ (这与第 60 轮给你的 Play 预期 1/1/1/3/1 一致)。 - 下一步:桌面侧已无可推进项(除文档/看板维护)。等你的 6 项决策。
- 新增
- 第 70 轮 ·
ClientItemType语义修正落地(BUG-023 ② 关闭)+ 发现"装备判定永远失败"的真缺陷- 背景:你早前已同意方向("
Type=1货币 /Type=3消耗品 /Type=2表内无,改名与用法待做"),本轮落地。 - 表实测(再确认):
Item.json共 9 行 ——Type=1:点数 / 源晶 / 晶核(货币);Type=3:启迪之星 / 共鸣结晶·绿蓝紫橙红(消耗品);Type=20 行。 - 改动:
· 枚举按表对齐:
Unknown = 0/Currency = 1/Consumable = 3,2不设成员(表内无该值 ⇒ 语义未定义,不猜); · 5 处硬编码改为表驱动ResolveItemType(itemId)(邮件附件 / 活动奖励 / 两条奖励循环 / 任务奖励)—— 原先它们写的是ClientItemType.Material(=1,正是"货币"的值),属语义错位; · 配置层本来就是对的:ClientItemConfig.Type的注释已写明"1= 货币、3= 消耗品;2表内未出现" ✓ 错只在领域枚举与本地模拟。 - 🔴 副产物:一个真缺陷 —— 表内没有任何"装备"类型,而
TrySetEquipmentEquipped依赖ClientItemType.Equipment(值2) ⇒ 该判定永远失败(装备功能实际不可用)。为不擅自引入未确认的产品规则,改为显式IsEquippableItem(item)(当前恒 false)- 明确失败原因"装备功能尚未接入(配置表暂无装备类型)",行为与原先完全一致。等负责人确认装备的数据来源(配置表?服务端?)。
- 验证:编译三目标 0 error;新增
ClientTableProbe.VerifyItemTypeMapping()(菜单Client/配置表/验证道具类型映射(领取路径)) 真的执行"一键领取邮件附件"(ClaimAllMails)再逐项比对 —— 实测[验证] 一键领取邮件附件:2 封、入包道具 110004(表 Type=3)ItemType=Consumable 期望=Consumable ✓、 结论行"与配置表完全一致"(Logs/verify-itemtype.log,error CS 0/ 异常 0)。 另在基线探针里加了不变式自检(背包项ItemType必须等于表Type的映射),Logs/b1-prebuild-baseline2.log三项全 ✓。 ⚠️ 工具坑复现:PowerShellout-lineoutputNullReference 又出现一次(已知问题),重跑同一命令即成功 —— 已在文档里记为已知现象。- 下一步:等负责人拍板(构建入口 A/B/C 等 5 项)。本轮是"你已同意方向"的最后一项可落地内容; 之后桌面侧仅剩"保持文档/看板同步",其余都需你的决策或美术资源。
- 背景:你早前已同意方向("
- 第 69 轮 · 客户端启动阶段判定表(真机日志"卡在哪一步"速查)
- 取证结论(启动链):场景根节点 =
ClientBootstrap+ClientCanvas+EventSystem平级;ClientCanvas下为PopupLayer/PagesLayer/SystemLayer/ToastRoot; 入口组件 =ClientCanvas上的ClientShellController+ClientUiNavigator+ClientSystemFeedback+ClientUiClickTracer; 真正的数据初始化在ClientBootstrap.cs:12-14(ClientServices.InitializeForDevelopment()→[Client] Local development data initialized.)。 ⚠️ 重要限制(已写入文档):工程没有ProjectSettings/MonoManager.asset⇒ 未配置脚本执行顺序 ⇒ 各Awake/Start先后未定义。因此判定表按"哪条标记缺失"使用,不能按"顺序对不对"判断。- 7 个启动标记 + 缺失含义(写进
WEBGL_B2_DIAGNOSTICS.md§2.2):[配置表] 数据源:…/[配置表] 其他:道具 N(…)/[Client] Local development data initialized./[Client] 组合根注入完成:弹窗宿主 N 个,提示宿主 N 个。/[Client] PopupLayer 收录弹窗:按 pageId 路由 N …/[Client] 从场景自动收录 N 个未登记页面。/[Client] 导航能力已注入 N 个页面视图,导航观察者 N 个。 - 典型组合判读:① 一条都没有 ⇒ 场景没加载或卡在 Wasm/资源初始化(走 §3/§4 采集,先别怀疑表或 UI);
② 有"data initialized"无
[配置表]⇒ 配置服务初始化失败;③ 有数据源但解析失败>0⇒ 表链问题(=真机验证点①); ④ 有组合根/导航标记但无页面数据日志 ⇒ 页面未进入,取ClientUiTrace的导航/弹窗追踪行。 - 另记录:运行时关键动作由
ClientUiTrace.Line("导航"/"弹窗"/"追踪", …)输出,真机采集时要保留这些行(它们是"点不动/关不掉"类问题的证据)。 - 本轮无代码改动(纯取证 + 文档;按纪律不预先加日志代码)⇒ 无需重新编译。
- 下一步:等构建入口决策(
BUG-025)。桌面侧剩余可做项已不多,主要转为保持文档与看板同步、以及在你给规则后接剩余缺口。
- 取证结论(启动链):场景根节点 =
- 第 68 轮 · 构建前全量基线探针(真机比对基准)+ 顺手验证了 ProfilePage 的 Play 预期
- 新增
ClientTableProbe.LogFullBaseline()(菜单Client/配置表/打印构建前全量基线):在既有覆盖之外补上 运行环境 / 玩家状态层 / 各页面数据条数 / 收藏品三层对账(表内可见 · 已拥有 · 使用中),一次跑出可复查的基准。 - 实测(
Logs/b1-prebuild-baseline.log,error CS 0/ 异常 0 / 解析出错 0): · 平台WindowsEditor、读表路径本地 Resources/Table、表汇总 可用 10 / 空 0 / 缺失 0 / 解析失败 0、Hero = 54 行(可见 49); · 英雄列表 49 个(首个13003 蝎子精 / 元素1(光) / 品质3);Stats页签数 3、普攻 捣药杵击、属性 id1 = 1500; · 玩家体验玩家 / local-player / 战力 100【待确认】;主页展示与主力英雄均13003;编队队伍0/4、当前队伍战力 0;装备弹珠marble-001; · 背包 3 / 商城 3 / 卡池历史 0;邮件 2 / 任务 2 / 公告 2 / 弹珠 2;排行榜 战力 5 / 挑战 5;活动任务 Newbie 5 + Advanced 5;赛季活动 6; · 收藏品(表内可见/已拥有/使用中):Head1/1/10001、Badge1/1/10002、Nameplate1/1/10001、HeadFrame3/2/10002、Title1/1/10002。 - ★ 顺带验证了第 60 轮给你的 Play 预期:我当时说"收藏品应显示 头像 1 / 徽章 1 / 铭牌 1 / 头像框 3 / 称号 1", 本轮基线正好是 1/1/1/3/1 ✓ —— 说明 Play 验收时列表条数应与此一致。
- 已写入
WEBGL_B2_DIAGNOSTICS.md§2.1(含复现命令与真机判读须知:不要用"数量不同"直接推断服务端或配置问题)。 ⚠️ 我又犯了一次"不查就写":新方法里我猜了枚举成员(ClientLeaderboardKind.Battle、ClientActivityTaskCategory.Seasonal), 编译报 2 个CS0117。查证后:ClientLeaderboardKind = { BattlePower, Challenge }、活动任务只有Newbie/Advanced(赛季内容走GetActivities(),不是任务)。 教训:任何类型/枚举/方法名都要先 grep 定义再写,不允许凭印象拼。- 数据层观察(非缺陷,待确认):
玩家战力 = 100而当前队伍战力 = 0—— 两者口径不同(前者本地模拟展示值,后者是队伍各槽位英雄战力之和,而英雄战力属服务器下发),展示口径需负责人确认。 - 下一步:等构建入口决策(
BUG-025);桌面侧可继续的是把"客户端启动阶段清单"整理成文档(按纪律不预先加代码)。
- 新增
- 第 67 轮 · B1 构建清单 + B2 证据采集清单(两份可直接执行的移植文档)
- 新增
WEBGL_B1_BUILD.md:前置条件(含"BUG-025未定则构建无意义"的开工先决)、8 步链路 (① 命令行探针验证 → ② HybridCLR AOT/WebGL 热更 dll(Assets/Editor/HybridCLR/WebGLHotUpdateDllCommand.cs)→ ③ YooAsset 构包 [GUI] → ④ Unity WebGL 构建 [GUI] → ⑤ WX 转换 [GUI](WXEditorWindow/WXConvertCore,产物webgl/+minigame/、模板wechat-default)→ ⑥ 开发者工具预览 [GUI] → ⑦ 真机(授权人)→ ⑧ 归档)、逐步校验标准、失败排查表、证据归档命名约定。 明确标注 [GUI] 步骤由负责人执行,代理只备前置与校验。 - 新增
WEBGL_B2_DIAGNOSTICS.md:按AGENTS.md§4 纪律只列采集项、不写根因。 · 可用日志通路已确证存在:WX.SetEnableDebug(WX.cs:2294)、WX.GetLogManager(:4507)、WX.GetRealtimeLogManager(:4519)(真机黑屏最有用,可在小程序后台看,不必连线); · 客户端已有日志标签判读表:[配置表] 客户端读表路径…/汇总:可用 N 张…解析失败 N 张/ 逐表行数 —— 并给出桌面基准(Logs/pkg-verify4-local.log、Hero = 54 行); ·BUG-0098 条采集项(完整 Console≥30s、WebGL2 上下文、资源包初始化成功、[配置表]段是否存在、全部 Error 原文、缺失 Shader 完整列表、 首屏形态(黑屏/全白/有 UI 无 3D…)、清缓存复采、真机 RealtimeLog); ·BUG-0136 条采集项(game.json/app.json启动页字段只读、转换日志与产物、加载阶段日志序列、框架 js 与 worker 加载、默认首屏图); · 三个 WebGL 验证点的真机判据与失败时先采什么;真机回归矩阵(按 §5 B2,含记录格式"未测试不能标记通过"); · 最小可回收诊断仅作提案([Boot] N/4 …阶段标记 + RealtimeLog),等采集结果出来再决定是否加(现在加属无证据的猜测性投入)。 - 顺带确证(解决 B0 的"待采集"):YooAsset =
com.tuyoogame.yooasset2.1.1,位置Assets/Main/Yooasset(工程内本地包,故manifest.json里没有条目); 已同步更新WEBGL_B0_GATE.md§4 与 §7 并新增 §9 配套文档索引。 WX 转换器另有确证事实:WXConvertCore.cs强制PlayerSettings.WebGL.compressionFormat = Disabled、debugSymbols = true、 导出目录webgl//minigame/、框架文件名webgl.wasm.framework.unityweb.js、workerwebgl.worker.js、默认首屏图.../images/background.jpg。 - 本轮无代码/场景改动(纯文档)⇒ 无需重新编译。
- 下一步:等负责人定 构建入口 A/B/C(
BUG-025);期间可继续桌面侧可做的事(例如把客户端启动阶段的日志标签补成一份"阶段清单"以便真机判读 —— 但按纪律不预先加代码)。
- 新增
- 第 66 轮 · B0 迁移前门禁:逐条取证,抓到一个硬阻断
- 新增文档
WEBGL_B0_GATE.md(B0 门禁记录,供移植新会话直接使用):工具链版本与安装位置、WebGL 暴露面、 YooAsset/HybridCLR/XLua 兼容矩阵、首包/分包、真机环境、首次真机三个验证点、待负责人清单、证据索引。 - 🔴 硬阻断(
BUG-025):ProjectSettings/EditorBuildSettings.asset只有一个场景Assets/Main/Boot.unity; 全工程没有任何代码加载ClientShell(只有编辑器工具引用路径常量);Boot.unity里客户端引用出现次数 0。 ⇒ 按现状构建 WebGL,包内不含客户端场景,运行后永远到不了客户端 UI。 已给三个方案(A 加进清单并置首 / B 在 Boot 后追加加载 / C 新建ClientBoot场景),等负责人选。 - 已留档的工具链事实:Unity
2022.3.57f1c2;URP 14.0.11;TMP 3.0.7;HybridCLR(gitee git 依赖,无版本号,另有HybridCLRGenerate/); 微信小游戏 SDKcom.qq.weixin.minigame0.1.1(WXSDK,Tuanjie Engine Adapter);XLua 为工程内集成且含 WebGL 适配Assets/Plugins/WebGL/xlua_webgl.cpp。 WX 转换 GUI 入口在Assets/WX-WASM-SDK-V2/Editor/(WXEditorWindow/WXConvertCore/WXMultiPackageMergeWindow)。 - WebGL Player 设置两处风险:
stripEngineCode: 0(引擎代码剥离关闭 ⇒ 包体偏大)、webGLCompressionFormat: 2(Disabled); 其余:webGLMemorySize: 256、webGLInitialMemorySize: 32、webGLThreadsSupport: 0(线程关,与小游戏一致 ✓)、apiCompatibilityLevel: 6、allowUnsafeCode: 1。 - 待采集(不当作结论):
Packages/manifest.json里没有yooasset条目,但工程确实在用 YooAsset ⇒ 其实际位置与版本未确证,已标为待采集。 - 首次真机三个验证点已写入门禁文档:① 表读取链(
persistentDataPath/config.pkg+Unity.IO.Compression解压 + 回落Resources/Table); ②Span/stackalloc说明文本格式化;③Resources/Table体积(+174 KB)与首包/分包预算。 - 本轮无代码/场景改动(纯取证与文档)⇒ 无需重新编译。
- 下一步:等负责人定构建入口;同时可先在桌面侧把 B1 的构建步骤整理成可复现清单(不含上传/发布)。
- 新增文档
- 第 65 轮 · Rank 缺口可做部分已接:排行榜品质 / 立绘查找表 + 更正我自己的数量错误
- 做了什么:新增结构修复步骤
FillRankVisualTables(),按工程内实际贴图重建ClientRankPage的两张查找表: ·_qualities= 6 项(id2..6→QualityIcon_2..6.png,另加本地模拟占位 idquality-placeholder→QualityIcon_3); ·_illustrations= 5 项(id 为英雄号12001/13001/14001/15001→HeroPortrait_*.png,另加illustration-placeholder); · 刻意不填:_avatars(HeroAvatar_*)/_frames(AvatarFrame_*)/_badges(Medal_*)/_attributes(AttributeIcon_*)—— 工程内 0 个贴图,填了只会是空引用。 - 契约依据(不是猜):
ClientConfigModels注释写明资源名约定QualityIcon_<Quality>、HeroPortrait_<id>_c|_d; id 取自文件名后缀(AssetDatabase.FindAssets("QualityIcon_ t:Sprite")),因此将来美术补图后重跑一次即自动扩充。 - 证据:编译三目标 0 error;
Logs/repair-rankvisuals.logerror CS 0/ 异常 0 / 30 处变更; 场景 YAML 复核:_qualities6 项、_illustrations5 项均带 Sprite 引用(fileID 21300000+ guid),其余 4 张表为[]✓。 ⚠️ 更正我自己的数据错误(第 62 轮):我当时写「QualityIcon_*20 个 /ElementIcon_*10 个 /HeroPortrait_*8 个」—— 实测是 5 / 5 / 4(Get-ChildItem按.png计数)。已同步更正BUG_TRACKER与MODULE.md。 另一个实测发现:ElementIcon_*只有_1.._5,元素 6(暗)没有图。- 教训:数量类结论必须来自一次明确的计数命令,不能靠印象外推;报告里已写出的数字也要能回溯到命令。
- 仍未解:
_avatars/_frames/_badges/_attributes四类需美术补图(映射规则已明确:收藏品经Resources表得AvatarFrame_*/Medal_*等)。 - 下一步:B0 迁移前门禁(阶段 A 已收口到"等负责人拍板三处"的状态)。
- 做了什么:新增结构修复步骤
- 第 64 轮 · ActivityPage 缺口结案:没有缺口(又一条过时记录被推翻)
- 取证方法与结果(本轮最有价值的产出):把
ClientActivityPage里所有"按名查找"的字面量抽出来(30+ 个), 逐个到ActivityPage活动子树(687 节点)核对 —— 32/32 全部精确命中(含双空格的Newbie Task Button), 且数量自洽:12 张任务卡(12 ×任务进度条Canvas/领取+待完成键Button/进度条/已领取icon)、 60 个道具卡面(12 卡 × 5 奖励 ×道具卡面|道具名称|道具数量)、6 张赛季卡(6 ×活动标题|活动日期|红点|热门|标注文本)。 ⇒ UI 与代码的节点契约完全对齐。 - 数据也是真的:
ClientActivityPage读ClientServices.Data.GetActivityTasks(category), 而LocalClientDataService提供 新手 5 条 + 进阶 5 条 + 6 个赛季活动,并有TryClaimActivityTask/TryClaimActivity/TryClaimCompleteGuideEvent完整实现 ✓。 - 可达:大厅入口
ClientCanvas/PagesLayer/MainPage主页/downCanvas/ActivityButton存在 ✓,ClientHomePage.BindPrefabNavigation("ActivityButton", ClientHomeDestination.Activity)→ClientUiNavigator映射到ClientUiPageId.Activity✓。 - 唯一未接:
SetSpriteResolver/RegisterSprite(按 image id 取图的解析器)没有任何调用方 ⇒ 领取/待领取标签图标保持模板烘焙图; 与 BUG-023 的"资源标识无解析通路"同源,不是本页缺陷。 - ⇒ 正确结论:ActivityPage 是已实现、已对齐、已接本地数据、可从大厅抵达的页面;此前"只有结构/待实现"的记录过时。
- 顺带核实(入口清单):
ActivityButton= 1 ✓;TaskButton= 0、NoticeButton= 0 ⇒ 任务页与公告页在场景里没有入口(与"缺失页面显示开发中"一致);HomeDisplayButton/PersonalizeButton= 0(此前已记录,属历史兼容绑定,实际不命中)。 - 本轮无代码/场景改动(结论是"无缺口")⇒ 无需重新编译。
- 阶段 A 剩余:Rank 的"品质一类可接"(资源已具备)+ BUG-024 / RISK-020 / BUG-023 三处等负责人拍板,然后进入 B0 门禁。
- 取证方法与结果(本轮最有价值的产出):把
- 第 63 轮 · Mail 缺口结案:真实缺口只有一个(详情/状态无文本节点),另更正三条过时记录;看板已建
- 看板已启用(更正我此前"
board_*工具不可用"的错误结论):工具要求 POSIX 风格路径/d/unity project/pinball, 传D:\unity project\pinball会被拒为"must be an absolute path"。已建 3 个主任务 + 13 个子任务(阶段 A / 阶段 B / 两项 WebGL 降风险改造)。 - Mail 取证结论(
ClientMailPage组件实例1008869757): · 可用的:邮件列表走"1 模板 + 运行时克隆"✓,克隆体已绑SelectMail(index)✓,ClaimAll/TryClaimMail✓, 列表项显示邮件名称(含已读/已领取标记)、日期text、附件道具卡牌prefab*✓。 · 真实缺口:_detail(标题+正文+附件)与_status(领取状态)在场景里fileID 0, 且全页没有任何可接的目标节点 —— TMP 文本穷举只有列表项内的那几个;Email Title/Canvas/Emial title background frame/Email text整棵子树没有文本组件(那个叫Email text的节点其实是Image)⇒ 选中邮件看不到正文与状态。 ⚠️ 更正本页三条过时记录:①_emptyHint不是缺口 ——ResolveMissingReferences()运行时用Find("Default")自补 ✓; ②_mailLabels的 2 槽旧机制已被模板方案取代(代码注释已说明)✓;③ 邮件卡已有点击绑定 ✓。- 记档
BUG-024:给出三个方案(A 在现有面板下新增/改造一个 TMP 正文区/B 正文改用已有Email Details Page弹窗/C 维持现状只显示列表),等负责人选(不擅自新建 UI 节点)。 - 本轮无代码/场景改动(缺口属设计层,且 §4 要求不擅自建节点)⇒ 无需重新编译;文档改动已做文本核对。
- 下一步:ActivityPage 缺口(阶段 A 最后一个未取证页),随后 Rank 的"品质一类可接"与 B0 门禁。
- 看板已启用(更正我此前"
- 第 62 轮 · 资源映射规则已找到 + 美术盘点(推翻"规则未定义")
- 发现:
Resources表(256 行)的Id → SkeletonData就是"资源 id → 资源名"映射,收藏品ResId正是Resources.Id:Title51001→Title_51001、HeadFrame52001→AvatarFrame_52001、Nameplate53001→Nameplate_53001、Badge54001→**Medal_54001**(徽章资源名叫 Medal)。 - 美术盘点(按名搜
Assets,排除.meta):有 =QualityIcon_*(20) /ElementIcon_*(10) /HeroPortrait_*(部分,实测 8 个); 没有 =HeroAvatar_*/Title_*/AvatarFrame_*/Nameplate_*/Medal_*/Item_*/CatapultIcon_*/AttributeIcon_*。 - ⇒ BUG-023 ① 与 BUG-019 的阻断原因更正为"部分美术缺资源"(不是"规则未定义"):品质 / 元素 / 立绘可立即接,其余等美术补图或确认走热更包。
- 另发现一处"接口与 prefab 对不上":卡prefab 有
品质Image/属性图标Image节点,但ClientHeroCard没有对应字段 ⇒ 卡片要显示品质/元素徽标需加字段 + 接线。 BUG-020已修并验证:_progressFill已接(场景复核fileID 1451101832),修复日志error CS 0/ 异常 0 / 19 处变更。- 文档修整:本文件第 57~61 轮的"轮次标题"此前被我插错位置(标题挤在一起、正文交错、顺序倒置),本轮按每轮首条 bullet 的标记重排; 现约定 最新轮次放在最上,新增轮次请插在当前第一条轮次标题之前。
- 发现:
- 第 61 轮 · 阶段 A 收口:两个"关不掉的弹窗"结案(其中一条是过时记录)
- 结论(有代码/场景证据):
·
Purchase Success Page并不存在"关不掉"问题 ——ClientShopPage第 233 行Set(_success, true)打开它, 第 288 行BindSuccessDismissHandlers()在运行时遍历它的全部Graphic、恢复raycastTarget并补ClientShopCloseOnClick(→CloseSuccessPage), 注释里写着负责人要求"点击任何地方直接退回购买界面" ⇒ 关闭路径完整 ✓ ·Success Receipt Interface是"死内容":全工程只有结构修复工具里的LayerMove引用它, 没有任何运行时代码打开它;根节点没有 Image(无点击区)、子节点也没有 Button ⇒ 既打不开也无从关闭。 ⇒ 它不是可用性阻断项,而是"尚未确定用途的场景残留"(进入条件属产品决策)。记录为待确认,不擅自删除。 - 因此 MODULE.md §14 与旧总清单里"
Purchase Success Page、Success Receipt Interface交互节点数为 0,打开后无关闭手段"的说法已过时,本轮更正。 - 取证方法(可复用):① 用脚本把场景组件的
m_Scriptguid 解析成类型名(区分 TMP/UGUI Text/Image/Button/GraphicRaycaster); ② 用git/全工程 grep 找"谁打开它";③ 用ClientShopPage这类宿主页面的Bind/BindSuccessDismissHandlers判断"运行时是否补了点击处理"。 - 教训(与第 59 轮同源):审计文档里的结论会过时,接手前必须用当前代码/场景复核;本轮与上一轮各发现一条("主页展示有 9 张卡"、"两个弹窗都关不掉")都是过时记录。
- 下一步:继续阶段 A 的 Shop / Rank / Mail / Activity 缺口(BUG-019 / BUG-020 等)。
- 结论(有代码/场景证据):
·
- 第 60 轮 · ProfilePage 收口执行完成(5 个收藏品列表 + 主页展示 + BUG-018),等 Play 验收
- 工具侧(
ClientShellStructuralRepair): ①ListTarget增TemplatePrefix—— 实测这些列表的第一项常是"未解锁"节点(徽章未解锁Image (3)), 直接取items[0]会把未解锁项当模板;现在按前缀优选(已解锁),并删除除模板外全部内联项。 ② 新增FindByPathTrimmed兜底 —— Unity 用单引号包裹带尾空格的节点名(m_Name: 'Panel_Personalize ',真实名字尾部 2 个空格), 把尾空格写进 C# 字面量极易被吃掉,故每段按Trim()匹配。 ③ 新增EnsureProfileShowcase():主页展示容器是空的 ⇒ 用PrefabUtility.InstantiatePrefab新建隐藏模板卡(保留 prefab 关联)+WireHeroCardOn补组件/接线。 ④ 新增WireProfileTexts():按路径取 TMP 组件接到_playerName/_playerId/_combatPower。 ⑤ListTargets增 5 条 ProfilePage 收藏品列表(Approved=true,负责人已授权)+ClientProfilePage分派分支。 - 场景写入结果(
Logs/repair-profilelists.log,error CS 0/ 异常 0 / 共 53 处变更): · 5 个容器各剩 1 个 inactive 模板:头像Item[0]/徽章Item[0]/铭牌Item[0]/头像框Item[0]/称号Item[0]✓ 模板选取正确:徽章已解锁image -> 徽章Item、小铭牌已解锁image -> 铭牌Item、称号已解锁-无image -> 称号Item(没有被未解锁项抢走)✓ ·展示卡Item已新建(prefab 实例)+ 已挂ClientHeroCard+_showcaseTemplate/_showcaseRoot已接线 ✓ ·_playerName / _playerId / _combatPower三条 TMP 文本已接线 ✓;ClientProfilePage共 15 个字段全部非 0 ✓ - 代码侧:新增
ClientCollectionItemView(只写控件)/ClientCollectionList(1 模板 + N 实例,范式与ClientHeroCardList一致);ClientProfilePage重写:TMP 字段类型(BUG-018 根因)+ 5 列表 + 主页展示 + 文本绑定 + 点击装备(未拥有给提示,不报错)。 ⚠️ 本轮我造成并已修复的事故:重写ClientProfilePage时没读全原文(读取被截断)就整文件覆盖, 丢掉了BindPageActions/BindButton/CancelRename/ConfirmRename。已从 git diff 恢复原始语义补回。 关键事实:场景里唯一的 UnityEvent 是 3 个SetActive,没有任何按钮通过场景事件调用这些方法 ⇒ 丢失后表现是"按钮没反应且不报错"。 教训:覆盖整文件前必须完整读取原文件(读取被截断时先取回全文)。- 🔍 工具盲区(已记录):prefab 实例根节点的名字存在
PrefabInstance的m_Modifications(propertyPath: m_Name)里, 不在 GameObject 文档中 ⇒ 我的场景解析脚本扫不到它(首轮因此误判"展示卡Item 不存在")。判定实例类节点要另查 PrefabInstance 块。 - 待验收(请 Play 个人中心):5 个收藏品列表应显示 头像 1 / 徽章 1 / 铭牌 1 / 头像框 3 / 称号 1(按
ClientShow过滤的真实条数),未拥有的显示"未解锁"子节点; 玩家名 / 玩家ID / 战力 应有值(王…/玩家ID: …/战力数值);主页展示应有 1 张卡(点击进"主页展示"页更换)。 ⚠️ 已知未接:收藏品图标未解析 ——ResId(整型资源 id)→ Sprite 的映射规则未定义(与BUG-019同类阻断),Head用的HeroAvatar_*贴图工程内 0 个; 故当前保持模板图。需要负责人给出映射规则或认定可用贴图后补接。
- 工具侧(
- 第 59 轮 · 阶段 A 收口启动:ProfilePage 取证完成 + 两个新组件落地(未写场景)
- 负责人决定:SystemLayer 先不动,要影响分析(→ 已记
BUG_TRACKER.mdRISK-020,含 A/B/C 三方案与推荐 C); ProfilePage 场景写入全部授权(主页展示 + 5 个收藏品列表);BUG-018 可以一起做。 ⚠️ 先纠正一处我自己的失实:上一轮我口头说"已记入 RISK-020",实际没有写入文件 —— 本轮已补上(BUG_TRACKER.md共 373 行)。教训:说了写了就必须真的写。- BUG-018 精确定位(含组件类型核对,AGENTS.md §4 要求):场景里这三个文本是
TMP_Text(guidf4688fdb…), 而ClientProfilePage把它们声明成了旧版UnityEngine.UI.Text⇒ 违反 §4,需改字段类型。节点: · 玩家名 =Panel_Profile/底框/玩家名称Image/Text (TMP)· 玩家ID =Panel_Profile/底框/玩家IDImage/Text (TMP)(另有downImage/ID卡底框Image/Text (TMP)= ID 卡号码) · 战力 =Panel_Profile/MiddleImage/Panel1/战力底框/Text (TMP)(另有战力排行Image/Text (TMP)) - ProfilePage 列表结构取证:
Panel_Showcase/展示卡牌Scroll View 1/Viewport/Content= 空容器(0 项); 5 个收藏品容器各自Content_*/*Scroll View/Viewport/Content,条目名形如头像已解锁Image (2)/徽章未解锁Image (1)/小铭牌已解锁image/称号已解锁-无image; 每个"已解锁"条目内部已带一个未解锁子节点(头像已解锁Image/头像未解锁Image/Image)⇒ 1 模板 + 切锁子节点即可表达拥有/未拥有。 - 新增两个组件(编译通过,尚未接场景):
Assets/Client/Runtime/UI/ClientCollectionItemView.cs(只写控件:图标/未解锁子节点/使用中标记/点击;值没变不写)、ClientCollectionList.cs(1 模板 + N 实例,多余的隐藏不销毁;与ClientHeroCardList同一范式,且不依赖领域模型)。 - 已核实不是回归:ProfilePage 下从来没有
角色卡牌Button-final 1(最老备份与当前场景都是 0);ConvergeKnownLists白名单只有 Shop/Mail/Hero/Formation 四个容器,没碰过 ProfilePage; 审计里"主页展示有 9 张英雄卡"的说法与实场景不符(该容器一直为空)。⇒ 主页展示列表必须新建 1 张隐藏模板卡(已获授权)。 - 下一步:① 扩展
ListTarget/ConvergeKnownLists支持 ProfilePage 6 个列表(注意已解锁image小写 i 与称号已解锁-无image的命名陷阱); ② 改ClientProfilePage(TMP 字段类型 + 5 列表 + 主页展示 + BUG-018 文本绑定 + 点击装备);③ 编译 → 场景写入 → 探针/场景复核。
- 负责人决定:SystemLayer 先不动,要影响分析(→ 已记
- 第 58 轮 · 两项 WebGL 降风险改造(①②)完成并运行时验证
- ①
ClientTableSource的 gzip 换成工程同款Unity.IO.Compression:Assets/Unity.IO.Compression/Unity.IO.Compression.asmdef未写autoReferenced: false⇒ 默认true,Assembly-CSharp 可直接引用 ✓; 已把using System.IO.Compression;换成using Unity.IO.Compression;(与TableLoadHelper同源),消掉"WebGL 下System.IO.Compression未验证"这个未知。 - ②
ClientServerPcSession加平台条件编译:该组件挂在 ClientShell 场景里(guid 出现 1 次)⇒ 不能整体编译掉(会变 Missing Script)。 做法:#if UNITY_WEBGL && !UNITY_EDITOR下留同名空壳 MonoBehaviour,其余(TcpClient/System.Net.Sockets/Task.Run/ 网关反射发现)整段进#else不参与编译 ⇒ 小游戏包不再带 PC 网络栈。 - 验证(
Logs/pkg-verify*.log):Roslyn 三目标 0 error,且 WebGL profile 也 0 error(证明引用解析成功 + WebGL 分支走空壳); 命令行 Unity 全工程编译 + 探针 0 error / 0 异常。 - ★ 额外收获:首次验证了"远端表"整条链。方法(可复用,建议 B 阶段照用):
用 PowerShell 造一个合法 pkg(
GZip → [version=1byte] → 反复 [utf8\\0][utf8\\0])放到{persistentDataPath}\\config.pkg, 并把里面的Hero变异成只有 3 行;探针实测读表路径:远端落盘包 config.pkg(1 张表)+Hero = 3 行+英雄列表 = 1 个⇒Unity.IO.Compression解压、pkg 解析、远端优先、按表回落全部在真实运行时证明有效(不是空内容的弱测试)。删掉 pkg 后再跑 ⇒本地 Resources/Table+Hero = 54 行✓ 回落正确。 ⚠️ 又一次 PowerShell 坑(第 3 次同类):测试夹具用@(@("Hero", $json))会被展平成("Hero", $json),导致$pair[0]="H"、$pair[1]="e"—— 夹具写坏、差点误判成客户端 bug。改用List[byte]+AddRange后一次通过。数组展平是本机 PowerShell 的高频陷阱。- 下一步:阶段 A 收口 —— ProfilePage 收藏品列表 / Shop·Rank·Mail·Activity 缺口 / 两个无法关闭的弹窗 / SystemLayer 分层定案。
- ①
- 第 57 轮 · 新建
Stats模块(数值与说明)—— 按负责人架构原则一次到位- 负责人原则原话:数据只由权威服务器计算并分发,客户端负责 属性接口、技能/天赋数值接口 与 逻辑说明显示;单独成模块,贴近 MVC,强解耦 / 拓展性强 / 维护方便 / GC 消耗少,且"这是所有代码和设计的原则"。
- 新增 17 个文件(模块根
Assets/Client/Runtime/Stats/,自带MODULE.md):Model/(7:属性 id / 属性值 / 能力种类 / 页签 / 能力状态 / 能力条目+页签+英雄能力集,纯 C# 零 UnityEngine 依赖)、Gateway/(2:IClientStatsGateway服务端契约 +LocalClientStatsGateway扮演服务器)、Service/(3:★ClientAbilitySectionRule唯一映射点 + 接口 +ClientStatsService)、Format/(2:说明文本接口 +ClientDescriptionFormatter)、View/(4:图标解析委托 + 属性行 / 能力条目 / 能力页签三个 View)。 - 硬约束已落到代码:接口里没有任何"计算"形态的方法;配置表只被 Service / Format / Gateway(扮演服务器时)读取;本地模拟只在 Gateway 里;说明文本只有
Format/一个出口,View 不拼字符串。 - GC:能力集合按英雄建一次原地刷新;属性用复用列表;查询全
for+索引(无 LINQ/无接口foreach);说明文本(id,level)缓存且"无分档时直接返回模板字符串本身";View 值没变不写控件;强化列表对象池;事件用缓存委托并在Dispose解除。 - 验证(
Logs/stats-module-probe3.log;Roslyn 三目标 0 error + 命令行 Unity 全工程编译 + 探针):error CS 0/配置表解析出错 0/ 异常 0;3 个页签 = 天赋(玉兔灵药) / 秘技(月华追踪) / 终结技(广寒月影)、普攻 = 捣药杵击; 格式化自检:等级1=…8%…、等级15=…9%…、末段共用后缀(等级20)=…80%…、单个数字不动; 属性(英雄 13003):Hp1500 Atk480 Def160 Spd65 暴击400 暴伤14500; 被动归属自检(13001):天赋 12 条 / 秘技 1 条(秘技强化描述点名"月华追踪"⇒ 正确归秘技)/ 终结技 0 条。 - 顺手修掉我自己的一个设计错误:原先
GetHeroSkills/GetHeroPotencies/TryGetHero只查"前端可见"的英雄, 而"能不能按 id 查定义"与"列表要不要显示它"是两件事 ⇒ 新增_heroByIdAll(表内全部)与_heroById(可见)分开。 ⚠️ 数据侧发现(待负责人知晓,非代码问题): ① 49 个可见英雄的被动数据全是占位[1,2],有完整被动数据的 4 个英雄(13001/14001/14007/15001)ClientShow全为 0 ⇒ 正式数据补齐前,可见英雄的天赋页必然空态(已按"空着、不报错"处理)。 ② 被动300112 天赋冷却与300113 秘技冷却描述完全相同(都是"天赋技能冷却-1回合",疑似漏改)⇒ 按弱关联判断时秘技冷却被兜底归到天赋页。- 说明文本格式的实测纠正:分档是每段各自带单位(
8%/9%/10%,码点0038 0025 002F 0039…),不是我原先假设的"只有末段带%";现已两种都支持。 - 设计与约定见
Assets/Client/Runtime/Stats/MODULE.md(含目录、MVC 边界、GC 清单、禁止事项、6 条待确认项)。 - 下一步:接页面(
ClientHeroDetailPage三个页签改成只绑ClientHeroAbilitySet,属性行绑GetAttributes);ClientItemType语义修正。
A. 未验收通过的页面
| 页面 / 弹窗 | 验收 | 主要缺口 |
|---|---|---|
HeroPage英雄 |
✅ 已验收 | — |
HeroDetailPage英雄详情主页 |
✅ 已验收(BUG-016 / 017 已关闭) | — |
FormationPage编队 |
✅ 已验收 | 元素筛选(明确不做)、搜索、查看卡面信息tips 未实现 |
ShopPage商店 |
⛔ 未验收 | 卡面售价待 Play 核对;购买数量进度条未接线(BUG-020) |
ProfilePage个人中心 |
⛔ 未验收 | 玩家名/ID/战力不显示真实数据(BUG-018);个性化 5 个真列表 + 主页展示 9 张卡无数据源(§14) |
MailPage邮件 |
⛔ 未验收 | _detail / _status 未接线;邮件详情无打开逻辑 |
RankPage排行榜 |
⛔ 未验收 | 6 张精灵表全空(BUG-019) |
ActivityPage活动 |
⛔ 未验收 | 行为已正确但结构未收敛(需一次场景写入) |
Complete Guide Event Page全图鉴活动 |
⛔ 未验收 | 无实际逻辑 |
Product Purchase Interface、Purchase Success Page、Success Receipt Interface、Exchange code interface、Historical Order Interface、Pending shipmentCanvas、Email Details Page(Have)/(No)、Player lineup、联系客服Page |
⛔ 未验收 | 多为 routed=0(仅按引用打开);其中 Purchase Success Page / Success Receipt Interface 交互节点数=0,打开后无法关闭 |
B. 未实现的功能
- 整页缺失(有
pageId路由、场景无页面):扭蛋 / 背包 / 任务 / 公告 / 弹珠 —— 现由首页「开发中」提示兜底;HeroEnhance连 UI 入口都没有。 ProfilePage个性化:头像(5) / 徽章(5) / 铭牌(9) / 头像框(2) / 称号(3+3) 五个真列表 + 主页展示 9 张卡 ——IClientDataService无任何集合 API,ClientItemType也没有这些分类。- 排行榜:头像/框/徽章/立绘/属性/品质的 id → sprite 映射未定义。
- 邮件:详情/状态区无数据;
Email Details(Have)/(No)与Success Receipt Interface代码里没有任何打开逻辑。 - 购买完成链:
2026-09-20 第 61 轮更正:Purchase Success Page、Success Receipt Interface交互节点=0。Purchase Success Page由ClientShopPage.BindSuccessDismissHandlers()在运行时补ClientShopCloseOnClick⇒ 可关(不是阻断项);Success Receipt Interface不可达(无任何运行时代码打开),属待确认的场景残留。 - 红点系统:邮件/公告红点无节点(全场景只有
ActivityButton/RedDot)。 - 加载页:接口已备好(
ClientLoadingService),未接入启动流程 —— 归移植会话。 - 弹窗遮罩:
ClientPopupService._maskRoot空 ⇒ 不阻断背后点击。 - 编队:元素筛选(负责人明确不做)、搜索、
查看卡面信息tips。 - 英雄详情底部 4 键:
BottomFunctionIconView._icon/_label未接线。
C. 潜在隐患
- 架构一致性:
SystemLayer恒 inactive,与HANDOVER_PLAN.md§3(SystemLayer 承担 Loading / 遮罩 / Toast / Tips)冲突;本轮把 Toast 临时挂到ClientCanvas⇒ 偏离待负责人裁定。 - 文档过期:
MODULE.md§14 对编队的描述已过期(编队已实现验收、选卡已收敛为 1 模板、_slot/_status已删),会误导后续会话(AGENTS.md §6 要求同步)。 - "静默失效"惯犯:全场景 39 个组件带未接线字段,表现是"看着正常、其实是美术占位字" ⇒ 验收极易漏(BUG-018 ~ 020、RISK-015 已记;RISK-016 为良性排除清单)。
- 本地模拟数据单薄:9 个英雄,无任务 / 公告 / 扭蛋 / 称号等集合 ⇒ 验收覆盖面不足。
- 工具盲区:只读脚本看不到 prefab 实例内部(历史误判来源);场景中文为转义存储;
pwsh是 PS 5.1 且按 ANSI 读脚本(中文注释会让脚本解析崩)。任务看板board_*不可用,进度只能靠本文件。 - 移植相关:
Init.cs的Debug.LogError(progress)每帧刷 error(会淹掉真机日志、妨碍排查黑屏);WebGL 未结项 —— BUG-009(首屏黑屏 + URP shader)、BUG-013(app.json启动页)调查中,BUG-005/007/008/011/012/014 待验证,BUG-010/015 待重传/重转。 - 仓库状态:工作区存在大量未提交改动与未跟踪产物(
Bundles/WebGL719 MB 等)⇒ 回滚与交接风险;RISK-014挂着清理待办。 - 基础设施已知重复:
LitJson重复程序集(RISK-007)、Timeline AOT 元数据(BUG-008)。
FormationPage本轮落地(第 38 轮,全部纯代码、未写场景)
- 数据契约(
IClientDataService+LocalClientDataService,本地模拟、可替换):新增GetFormationTeams()/GetFormationTeamIndex()/TrySwitchFormationTeam(int)/TrySetFormationSlot(int, string)/GetFormationCombatPower(int);新增领域模型ClientFormationTeam(SlotCount=3、TeamCode、SlotHeroIds)。队伍数 4 与槽位数 3 取自场景节点,非杜撰。旧的单槽GetFormationHeroId()/TrySetFormationHero()保留为兼容写法 = 「当前队伍槽位 0」,_formationHeroId字段已删除(单一数据源,§12.4)。- 卡牌管理器(§13):
ClientHeroCard.SetTeamSlot(slotNumber, numberSprite=null);ClientHeroCardList.Show(..., Func<T,int> teamSlotOf, onClick)重载。⚠️ 编号数字实测是 Image 而非文本,写不了数字,只能换 sprite → 数字贴图来源待确认。- 页面接线:
ClientFormationPage由 38 行扩到完整实现 —— 3 槽位、4 队伍(左/右Button +编组号-Text)、英雄选择列表(ClientHeroCardList)、战力文本、后退Button;_slot/_status全部判空。- 刻意不实现(映射未定义,避免把猜测当规则):① 元素筛选 全/光/水/土/风/火/暗 与数据侧
Element("Fire"/"Water") 的对应;②选中点1..4的当前队伍高亮表现、确认键Button语义。- 场景写入已完成(第 39 轮;负责人授权“自动关和开”,由代理执行):
RepairAll跑了两遍。 第一遍暴露一个顺序 bug:ConvergeKnownLists()排在卡牌接线之前,收敛先把选卡改名成编队英雄卡Item、删掉其余 8 张,之后按原名角色卡牌Button-final*找就0 张(日志原文:编队卡牌-Panel 下接线卡牌 9 处/Scroll View/.../Content 下接线卡牌 0 处)。 修正为「接线在收敛之前」并让匹配器同时认收敛后的模板名(保证幂等)后,第二遍 14 处变更、无删除。- 场景文件复核(不信日志,只读解析场景 YAML):
ClientHeroCard全场景 2 → 6 处 (HeroPage 2 + 编队 3 张槽位卡 + 选卡模板 1);模板名编队英雄卡Item已改名且已禁用;ClientFormationPage._cardTemplate=fileID 2015043900、_cardListRoot=fileID 302072625,均非 0。- 备份:
Logs/ClientShell.before-formation-cards.unity.bak、Logs/ClientShell.before-formation-cards-2.unity.bak。- ✅ 已整页验收通过(负责人 2026-09-20:“哦牛逼,完美”)。验收确认的效果: 选卡 9 张(含 3 张带锁)参数各异;点卡即切换(自动补最小空位 / 再点移出且不补位 / 满员不加入); 编号
1/2/3显示在选卡上并随编队动态变化;3 个槽位格位保留(空槽卡面为空);左/右Button切 4 支队伍(编组号01→02…);战力随队伍变化。⚠️ 下方“元素筛选/选中点高亮/确认键语义未做”“_slot/_status待拖拽”等描述, 均已在第 40 / 41 轮处理完毕(详见对应段落)—— 保留原文仅为时序证据,勿据此重做。第 40 轮(负责人验收反馈 → 立即执行三件)
- 元素筛选:不做(负责人明确“不实现了”)。已删除
ClientFormationPage.SetElementFilter;ClientHeroPage.SetElementFilter是既有的空壳,未动。选中点1..4高亮:已实现。取证:4 个点是同一贴图、同一颜色(m_Color (1,1,1,1)、raycastTarget=0),工程里没有“选中态”变体 ⇒ 只能按 alpha 区分(_teamDotDimAlpha,默认 0.35,可在 Inspector 调)。另记:4 个点的名字编号与屏幕横坐标相反(选中点1在最右),代码按“名字编号 = 队伍编号”理解。确认键Button:已实现 = 确认并返回(_navigation.Back())。理由:本地模拟是即时写入(点卡即存),没有独立“保存”动作;若语义另有要求,改ConfirmTeam()一处。_slot/_status:硬阻塞,无法接。取证 —— 编队页只有 3 类文本节点(编组号-Text/战力/ 卡上的等级-Text,前两个已各有所属),查看卡面信息tips-Image/Image无文本子节点;且SystemLayer下只有加载Page,根本没有 Toast 节点 ⇒ClientSystemFeedback.ShowToast现在只会打警告。两个字段目前全判空、安全但无可见反馈。待负责人决定:指一个节点 / 批准新建一个文本节点(属新建 UI,需明确批准)/ 直接删掉这两个字段。- 本轮 Roslyn 三目标 0 error(
Logs/verify-compile-formation3.log)。第 41 轮(负责人三条要求 → 全部落地;本轮无需场景写入**)**
- 同队不可重复英雄(数据规则):
LocalClientDataService.TrySetFormationSlot中,若该英雄已在同队其它槽位 ⇒ 返回false且不改任何状态,由页面提示。依据负责人“原则上不能选重复的英雄”。(若日后想改成“自动把它从旧槽位移过来”,只改这一段。)- 空槽位:改为保留格位、只清空卡面 —— 新增
ClientHeroCard.SetContentVisible(bool),只切子节点、不动本节点。原因:槽位容器带HorizontalLayoutGroup,隐藏本节点会让其余槽位重排。同时空槽不再显示成“一张未解锁的卡”(不再走Apply(unlocked:false))。- 删除
_slot/_status:连同只服务它们的Configure(GameObject, Text, Text)一并删除;SetStatus改为Debug.Log("[Client] 编队:…");编辑器工具里那句“请拖入文本节点”的日志同步更正。原因:编队页只有编组号-Text/战力/ 卡上等级-Text(前两个已各有所属),SystemLayer下也没有 Toast 节点。- 本轮 Roslyn 三目标 0 error(
Logs/verify-compile-formation6.log)。第 44 轮(两条路径都能移出 —— 纯代码)
- 槽位卡也接上同一个 toggle:点槽位卡 = 点选卡上那张编号卡,二者都能把该英雄移出编队 (槽位里既然有人,
TryToggleFormationHero必然走“移出”分支、不补位)。 实现只在RefreshSlots里把onClick从null换成() => SelectHero(heroId)(捕获的是英雄 id,不是循环变量)。 选卡的 Button 与槽位卡的 Button 场景里本就都有(修复日志:“已有 Button 或未匹配到,跳过”)。- Roslyn 三目标 0 error(
Logs/verify-compile-slotclick.log)。第 45 ~ 47 轮(UI 收口:导航死目标 + 全局视觉 Toast —— 代码 + 一次场景写入)
- 第 45 轮 · 只读普查:全场景内联列表汇总落
Logs/verify-inline-census.txt;ClientUiPopup注册表显示可按 pageId 路由的弹窗只有 9 个(Profile / Hero / HeroDetail / Shop / Mail / Rank / Activity / Formation / CompleteGuideEvent),其余 10 个仅按引用打开。⚠️ 我误报过一次,已纠正:曾断言ClientProfilePage两个入口“点了没反应”。实测场景里根本没有HomeDisplayButton/PersonalizeButton节点,而BindButton用直接子节点查找 ⇒ 那两行是从未被调用的死代码;个人中心没有问题(3 面板切换一直由ClientProfileNavigationController负责)。教训:看到调用点先查节点是否存在,再下结论。- 第 46 轮 · 开发中提示:真正要处理的是
GachaButton/BackpackButton(场景中确实存在、确实会触发导航)。新增IClientHomeNavigation.CanOpenFromHome(destination)(查弹窗注册表 + PagesLayer 注册表);ClientHomePage.RequestNavigation先判定再导航,不可达则提示「XXX功能开发中」并返回(顺带不改底部页签选中态)。判定是动态的 —— 以后补页并注册后,提示自动消失、入口自动生效。- 第 47 轮 · 全局视觉 Toast(场景写入):取证到两处“只进日志”的根因 ——
ClientSystemFeedback._toastRoot为空(ShowToast只打警告)+ClientHomePage._notice是fileID 0(ShowNotice只 Console)。已在SystemLayer下新建ToastRoot+ToastLabel(深色半透明底 + 白字居中、raycastTarget=false不吞点击、字体沿用Assets/Resources_HotUpdate/Font/TextMeshPro/Tips SDF.asset、默认隐藏)并接线;ClientHomePage新增IClientFeedbackHost,ShowNotice优先走全局 Toast。- 场景复核(读场景文件):
ToastRoot/ToastLabel已存在;ClientSystemFeedback._toastRoot = 832108125、_toastLabel = 1405690691、_toastDuration = 2。备份Logs/ClientShell.before-toast.unity.bak;批处理 15 处变更、0 错误(Logs/repair-toast.log)。- 视觉规格是最小方案(居中偏下 640×104、
anchoredPosition (0,-400)、字号 30)—— 按验收意见随时可调,改EnsureSystemToast()一处。第 48 轮(修 Toast 报错:宿主改挂
ClientCanvas—— 场景写入 18 处变更、0 错误)
- 负责人在 Play 里报错,日志栈指向
ClientSystemFeedback.cs:66(StartCoroutine): Coroutine couldn't be started because the game object is inactive。- 根因(我的错):
SystemLayer在场景里恒为inactive——加载Page的activeSelf=1但父层关着,且没有任何代码激活SystemLayer(ClientLoadingPage只切自己)。第 47 轮我把ToastRoot与ClientSystemFeedback都放在该层 ⇒ ① Toast 处于 inactive 层级 根本显示不出来;② 组件自身在 inactive 物体上,协程无法启动。- 修法:
ClientSystemFeedback与ToastRoot/ToastLabel全部改挂ClientCanvas(组合根,恒激活);EnsureKernelComponents的安装位置同步改为 ClientCanvas,并移除 SystemLayer 上的历史残留。幂等 ——EnsureSystemToast()也会清掉 SystemLayer 下的旧ToastRoot。- 场景复核(读场景文件):
ToastRoot -> ClientCanvas/ToastRoot、ToastLabel -> ClientCanvas/ToastRoot/ToastLabel、ClientSystemFeedback宿主 =ClientCanvas(_toastRoot=1971698340、_toastLabel=1195055596)。备份Logs/ClientShell.before-toastfix.unity.bak;批处理Logs/repair-toastfix.log。⚠️ 顺带发现(未动,待负责人定):既然SystemLayer恒 inactive,其中的加载Page(ClientLoadingPage)也从未运行过(连Awake都不会触发)。是“暂时不要加载页”还是“漏了激活”属产品取向,本轮未做任何改动。第 49 轮(加载页直连入口 + Play 演示入口 —— 纯代码,未写场景)
- 负责人判断:加载页从没被调用,唯一能想到的用场是「登录成功后下载资源进大厅」的过渡。只读取证证实:
ClientLoadingPage全工程无运行时调用方;钩子其实已在Assets/Main/Init.cs(downloader.OnDownloadProgressCallback,第 405 行已算出progress = currentDownloadBytes / totalDownloadBytes),但驱动事件被注释、只剩Debug.LogError(progress)每帧刷屏。- 新增
Assets/Client/Runtime/ClientLoadingService.cs(命名空间Pinball.Client):给启动流程一个不依赖EventCenter静态事件总线的最小接口 ——Begin(text)/SetProgress(0..1)/SetProgressPercent(0..100)/SetLoadingText/Complete()/Hide()/IsShowing/Reset()。
- 显式接管
SystemLayer开关(该层恒 inactive,而加载Page自身activeSelf=1,一激活就全屏显示):Begin()打开、Hide()关闭,不让它常开。- 找不到加载页 ⇒ 全部 no-op + 只警告一次,绝不抛异常打断启动流程。
- 解析用
Object.FindObjectOfType<ClientLoadingPage>(true):一次性 + 缓存(因它身处 inactive 层、无法靠自身Awake注册),不是每帧轮询,符合 AGENTS.md §4。Complete()不自动隐藏 —— “满进度停留多久”由调用方决定后调Hide()(静态类不持协程/计时器,不替产品定停留时长)。- 顺带修掉一个既有 bug:
ClientLoadingPage.PlayFiveSecondPreview()只在自身SetActive(true)后StartCoroutine,但父层 inactive ⇒activeInHierarchy=false⇒ 协程报同一个错、画面也不出现(Inspector 那个“播放 5 秒加载演示”按钮一直是坏的)。已改为先经ClientLoadingService.Begin()打开层;演示结尾补Hide()(以前显示不出来,所以“演完不收尾”从未暴露)。- 新增 Play 模式演示入口(
ClientLoadingPageEditor.cs):菜单Client/加载页/演示 5 秒加载(走 ClientLoadingService)+ Inspector 按钮「走 ClientLoadingService 演示」。用EditorApplication.update计时、不往场景塞任何对象;它验证的是真实链路(含SystemLayer开关),也是启动流程接线的参照实现。- Roslyn 三目标 0 error;
ClientLoadingService.cs已进入 Editor 与 WebGL 两个 profile(Logs/verify-compile-loadingdemo.log)。第 42 轮(测试样本扩充 —— 纯数据,未写场景、未动美术)
LocalClientDataService._heroes由 2 个扩到 9 个(6 已拥有 / 3 未拥有:hero-002/hero-008/hero-009),名字 / 元素 / 等级 / 星级 / 战力各不相同,便于看卡面参数差异。立绘沿用模板(选卡的spriteOf返回null),没有任何美术改动。Element仍用数据侧既有的英文值,界面 光/水/土/风/火/暗 映射仍未定义。- 队伍预置:第 1 队 3 槽填满(
hero-003/004/005,打开即可看到选卡上的 1/2/3 编号);第 2 队 1 个(hero-006);第 3、4 队留空 —— 便于连续切 4 支队伍观察“编号随编队动态变化”。- 已核对不会溢出:编队页
Scroll View/Viewport/Content与已验收的商店列表组件完全一致(RectTransform + GridLayoutGroup + ContentSizeFitter),9 张卡不会被裁。- Roslyn 三目标 0 error(
Logs/verify-compile-mockheroes.log)。第 43 轮(编队点选改为“切换”语义 —— 纯代码,未写场景) 负责人明确的交互,取代原先“先点空位再点卡”:点卡即切换。
- 不在队中 ⇒ 自动补编号最小的空位(无需先选空位);
- 已在队中 ⇒ 移出它,其余槽位不补位(编号保持不动),该编号空出;
- 三个编号都占满 ⇒ 不加入(提示「编队已满(3 个编号都已占用),请先移出一位」);
- 同时空出 2 个及以上编号时,必须补编号较小的那个 —— 实现从下标 0 顺序找第一个空位,天然满足。 落地:规则本体在
IClientDataService.TryToggleFormationHero(heroId, out slotNumber, out failureReason)+LocalClientDataService实现;页面SelectHero只做提示与刷新。 同时删除页面的_activeSlot与SelectSlot(int)(“先选槽位”整套移除), 并让槽位卡不再承担点击(移出统一由“点选卡上已编号的那张”完成)。 Roslyn 三目标 0 error(Logs/verify-compile-toggle2.log)。FormationPage编队取证(第 37 轮,证据Logs/verify-formationpage.txt)- 场景意图(98 个可见节点 + 171 个 prefab 实例):
编队卡牌-Panel3 个槽位卡(含编队队内编号Image,默认关);页面分栏-Image/Panel选中点1..4 + 左/右Button + 编组号-Text[01](= 4 队伍);元素属性分类列表-Image全/光/水/土/风/火/暗 = 7 个筛选;搜索icon-image;战力框(战力文本99999);查看卡面信息tips-Image;确认键Button;Scroll View/Viewport/Content9 张英雄卡。- 契约只有单个:
GetFormationHeroId()/TrySetFormationHero(heroId)(且要求hero.IsOwned)⇒ 3 槽位 / 4 队伍 / 元素筛选 / 搜索 / 编队战力全无接口。ClientPlayerLineup.Cards是排行榜打榜阵容(ClientRankPage在用),不是自己的编队。- 场景结构也没就绪:9 张选卡与 3 张槽位卡都没有
ClientHeroCard—— 全场景该组件仅 2 处(HeroPage 的HeroSubPageprefab 修改 +GuideSubPage普通节点);且角色卡牌Button-final 1.prefab的卡牌名称Image没有文本子节点(HeroPage 的卡牌名称是WireHeroCard()新建的)。⇒ 要让这页的卡显示数据,需与 HeroPage 同款的场景处理。- 待办 7 定性:修复工具第 421 行原文「
_slot/_status需要负责人按实际意图拖拽」⇒ 属意图未定,不是漏拖。- 本轮仅修一个潜在 NRE:
SelectHero直接解引用_status(值为 fileID 0),已改为判空(Refresh本来就有)。ActivityPage取证结论(2026-09-20,证据Logs/verify-inline-lists.txt):子树 687 节点、15 组重名兄弟,全部在 Scroll View 下、全部带 GridLayoutGroup、零星级图标Image(与待办 4 无冲突)。结构=3 个真列表 + 12 个嵌套列表:新手任务(6×任务卡prefabs)、进阶任务(6×任务卡prefabs)、活动任务(6×活动底框prefabs),且每张任务卡内部还有 5×道具卡牌prefab奖励槽。⚠️ 但行为已经正确:ClientActivityPage.ApplyTask(第 445 行)用binding.Root.SetActive(exists)按GetActivityTasks()条数隐藏多余卡片,奖励槽同样按data.Rewards.Count隐藏多余项 —— 即“场景烘一批池子 + 运行时隐藏多余”,已满足“实例数恒等于数据条数”。 ⇒ 本轮若做,属纯结构收敛(池子 → “1 模板 + 运行时生成”),不是修 bug;代价是一次不可逆的场景写入,并需新建 2 个列表脚本(卡片列表 + 卡片内嵌套的奖励列表)。种子数据:新手 5 条 / 进阶 5 条 / 每任务 1 个奖励。 仍被阻断:ProfilePage(真列表无数据源,见MODULE.md§14)。有真缺口的候选:FormationPage(待办 7_slot/_status未接线)。
| 专项 | 结果 |
|---|---|
| 全局弹窗遮罩 | 已撤除;模态改由 ClientPopupService 逐节点屏蔽射线(ApplyModalState,含"栈空即恢复大厅"的安全网) |
| 弹窗层级 / 显隐 | 根因是嵌套 Canvas 的 overrideSorting(已清零);另修三处同源 bug:ClientUiPopup.Awake 自隐藏、Open 隐藏下层、ShopPage.Show 越权置顶 |
| 分辨率适配专项 | 清除 123 处非根画布 CanvasScaler;matchWidthOrHeight 0.5→0、关 pixelPerfect;13 个全屏型页面根+背景铺满、5 个底栏横向铺满;锚点规范确立(已验收) |
| 列表收敛 | ShopPage商店 130→46、MailPage邮件 263→63、HeroPage英雄 190→57(模板模式,均含内联回退) |
| HeroPage 五步 | ① 取证 ② 卡牌脚本解耦(ClientHeroCard / ClientHeroCardList)③ 子界面拆分(HeroSubPage / GuideSubPage)④ 子页切换 + 进度显示 + 页签选中态 ⑤ 详情页只读 |
| HeroPage 接线核对(第 33 轮) | 只读场景核对两项待验证均通过;另修掉 BUG-016(前往获取+已满级Button 从未绑定 onClick,已解锁英雄点了没反应);Roslyn 三目标 0 error |
| 详情页根因(第 34 轮) | 项 1/项 3 同源:OpenHeroDetail 的 Fallback(HeroDetail) 恒 null ⇒ Show() 从未被调用 ⇒ 只读不生效且 _currentHero 恒 null。已修(ClientPopupService.GetPopup + 导航器解析,BUG-017);顺带默认关闭性能探针([UI追踪][性能] + 场景规模);Roslyn 三目标 0 error |
- 页签选中态 —— 切换后只有一个发黄(已解决)。
- 详情页只读(BUG-017) —— 图鉴页点带锁卡,日志
只读=True,已作用于 5 个按钮;装备槽 4 槽 + 升级按钮点不动。负责人回复:“完美实现”。 - 只读范围(负责人明确,务必按此口径) —— 仅装备槽 + 升级按钮;天赋 / 秘技 / 终结技三个 Toggle 不受限制,任何时候都能切。早前把三个 Toggle 一并锁住属超范围实现,已撤除。
- 升级按钮(BUG-016) —— 已解锁英雄可点、有响应。
- 控制台噪声 ——
[UI追踪][性能]与 187 行“场景规模”统计已默认关闭(ClientUiPerfProbe._enabled = false)。 - 为复测临时加的状态量日志已按约撤除,未留在定稿代码里。
留档根因(一项缺陷同时造成“只读”与“升级”失效):
ClientUiNavigator.OpenHeroDetail原先用Fallback(HeroDetail)取页面节点,而Fallback只查_pageById,该表只收录ClientUiPage(全场景仅MainPage主页一个);弹窗登记在ClientPopupService._popupById,从不进该表 ⇒ 恒null⇒ 提前return⇒Show()从未被调用(页面能打开,却从不按所点英雄初始化)。已改为向弹窗服务GetPopup(pageId)解析。完整证据链见BUG_TRACKER.mdBUG-017。
- 列表收敛其余页面:
ProfilePage26 处、ActivityPage15 处 等。⚠️ 星级图标Image×175 是固定 5 星展示,不得模板化(审计逐页清单里那行“✔ 可安全模板化”是机械判断,以此条为准;审计工具自身在ClientHierarchyAudit.cs的说明里也承认它不是列表)。- ✅ 已完成并验收:
HeroPage英雄、FormationPage编队;ShopPage商店/MailPage邮件早已模板化。 ProfilePage:被数据源阻断(真列表无任何集合 API,见MODULE.md§14),暂勿动。ActivityPage:行为已正确(隐藏式池子),做的话属纯结构收敛,需一次不可逆的场景写入。
- ✅ 已完成并验收:
商店卡面数字语义→ 已确认:售价,已按此接入ClientShopPage.ApplyPriceBadge(写入节点 =道具数量)。待 Play 核对卡面确实显示售价。⚠️ 我第一版接错了:接到数量角标。解析道具卡牌prefab.prefab才看到它是纯 Image、没有文本(左下角数量黑底同)⇒ 写了也不显示。卡上只有道具名称/道具数量两个文本节点。教训:卡是 prefab 实例时,先读 prefab 源文件再接线,别凭名字猜。⚠️ 语义由页面决定:奖励 / 邮件场景下道具数量表示“数量”(ClientActivityPage绑它)。本次只动商店。
_TEMP_GuideMarker:创建代码已删(否则幂等的RepairAll会把它加回来);场景里的节点按负责人决定“保留不删” —— 勿自行删除。→ 两个字段已删除(场景内无可用文本节点,提示改走 Console,见第 41 轮)。ClientFormationPage._slot/_status未接线调试诊断待清理→ 已清:ClientUiTrace.Enabled = false一次性静音(可见性诊断 / 栈快照 / 显隐 / 路由 / 导航 / 点击),并移除 HeroPage 每次刷新的进度日志。调用点全部保留,改回true即可复查,无需重新埋点。board_*工具不可用(第 33 轮复测确认仍坏):对三种绝对路径写法均报project_path must be an absolute path⇒ 工具自身的路径校验缺陷;任务看板始终未建立,本会话以CURRENT_STATE.md承担进度记录。- 【下一个大方向】移植微信小游戏 WebGL 环境 + 真机测试(负责人 2026-09-20 提出,预计另开一个新会话)
→ 权威版已上移到本节顶部「🔜 移植任务交接」(网络事实 / 基础设施证据 / 难度评估 / 加载页接线点 / 架构偏离)。以那一节为准,下面仅保留“调用点”细节,避免两处各写一份(§12.4 单一 owner)。
- 加载页(
ClientLoadingPage)的唯一现实调用点就在这条线上。只读取证(2026-09-20):全工程无任何运行时调用方(只有自身 + Editor 预览按钮PlayFiveSecondPreview);而Assets/Main/Init.cs的资源下载流程钩子已齐: 第 372 行downloader.OnDownloadProgressCallback = OnDownloadProgressUpdateFunction,第 405 行已算出progress = currentDownloadBytes / totalDownloadBytes。⚠️ 但驱动事件被注释掉了(EventCenter…"更新下载进度"/"下载完成"),且进度是用Debug.LogError(progress)打出来的(每帧刷 error,真机日志会被它淹掉)—— 这就是加载页从未被调用的原因。⚠️ 前提:加载Page位于SystemLayer,而该层恒为inactive⇒ 接线时必须由下载流程显式控制SystemLayer.SetActive(true/false)(加载Page的activeSelf已是 1,一旦激活就会显示,不能常开)。 → 属移植会话范围(Init.cs是启动/原公司代码边界,本会话未改)。 - 其它潜在调用点(当前不存在):YooAsset 分包按需下载时的过渡遮罩;若登录与资源下载拆成两段,则再加一个“登录后过渡”。不建议把整屏加载页用于普通网络等待(那是 Toast / 局部遮罩的活)。
- 移植难度评估(2026-09-20,基于本仓库证据,非猜测):
- 已具备(不用再担心):
WX-WASM-SDK-V2已导入;Bundles/WebGL资源包 719.5 MB 已构建、OSS/CDN 链路已走通;HybridCLRData有 WebGL 热更与 AOT 数据;WebGLPlugins/下有完整 Lua 5.3 C 源(Lua 能在 WebGL 编译);原生插件.jslib/.wasm已在工程内。 - XLua 风险≈0:
Assets/Lua只有 7 个文件 / 1.2 KB —— Lua 基本没被使用,游戏逻辑是 C#。 - 已在追踪的启动链缺陷:
BUG-005~BUG-015(首包版本文件 404、SDK 追加/Assets、AOT 元数据、本地表缺失、资源重复地址、app.json启动页、首屏黑屏 + URP shader 不支持)。⚠️ BUG-009/BUG-013在 tracker 里仍标调查中,需按实际结果复核后再关。 - 风险排序(越前越容易翻车):① iOS 真机 WebGL2 / 内存 / 纹理压缩兼容;② 网络 —— 微信只有 WebSocket,若服务端是原生 TCP 需网关或协议转换,且粘包 / 心跳 / 断线重连在 WS 下行为不同;③ 包体与首启下载体验(首包 ≤4MB、总包受限、wasm 走 CDN);④ HybridCLR AOT 泛型补齐(新 API 会反复冒一次);⑤ UI 适配(刘海 / 长屏 / 安全区);⑥ 音频解锁、触摸、
onShow/onHide生命周期。 - 待负责人确认(直接决定工期):TCP 那条路是在真机还是开发者工具/编辑器上打通的?服务端是原生 TCP 还是已有 WS 网关?
BUG-009/BUG-013现在是否真的闭环?
- 已具备(不用再担心):
- 加载页(
全局提示缺口→ 已补(第 47 轮):SystemLayer下已建ToastRoot+ToastLabel并接上ClientSystemFeedback,全局ShowToast现在有视觉。主页“开发中”提示已改走它。仍留空的是ClientPopupService._maskRoot(弹窗遮罩槽位)—— 是否要遮罩由负责人定。
- §11 交付与验收:一次一页;负责人 Play 验收后才算完成;场景写入不可逆,写入前先说明并取得确认。
- §12 诊断纪律:① 排序不由层级单独决定(先查
Canvas.overrideSorting/sortingOrder)② 运行时读数不能当布局事实(以场景/Inspector 为准)③ 沿"谁能改变这个状态"用全局搜索穷举 ④ 验证结果而非调用(接线必须用场景文件核对,日志的非空判断会骗人)。 - 列表:1 模板 + 运行时生成;实例数恒等于数据条数(不足新建、多余隐藏,防累积)。
- WYSIWYG:Game 视图锁
753×1630(或同比例1080×2337)在 Game 视图里调;纵向安全区按最矮档1080×1920(画布高 1339)设计。 - 四个坑:再给节点加
CanvasScaler/ 勾Override Sorting/ 用世界坐标调位 / 底图硬拉伸(应用 9-slice)。
- 纯代码改动 → 不关 Unity,只跑 Roslyn 验证
& "D:\unity project\pinball\Logs\verify-compile.ps1" -Profile All,负责人Ctrl+R即可。 - 需要写场景 → 才关 Unity 跑批处理:
Unity.exe -batchmode -quit -projectPath 'D:\unity project\pinball' -executeMethod '<类>.<方法>',子进程传$env:ALLUSERSPROFILE='C:\ProgramData';改大范围前先备份场景(Logs/*.unity.bak)。 - 结构修复入口:
Pinball.Client.Editor.ClientShellStructuralRepair.RepairAll(幂等,白名单 +Approved验收闸门)。 - 只读普查:
Pinball.Client.Editor.ClientHierarchyAudit.RunAudit→Logs/hierarchy-audit.txt(九节:总览/全局问题/逐页/数据对照/全屏适配/Canvas 布局/顶部锚点扫描/HeroPage 取证/卡牌模板)。 - 只读场景事实核对(第 33 轮新增,不需要 Unity):
& "D:\unity project\pinball\Logs\verify-scene-facts.ps1"→Logs/verify-scene-facts.txt。直接解析ClientShell.unity重建节点树,输出目标按钮/Toggle 计数、Animator controller 参数、Button.m_OnClick持久监听数;Unity 开着也能跑,用于在麻烦负责人 Play 之前先证伪“接线其实没接上”。⚠️ 两个坑:①pwsh实为 Windows PowerShell 5.1,脚本必须纯 ASCII(含中文的 UTF-8 无 BOM 脚本会被按 ANSI 解析而报Missing closing '}'),中文节点名用[regex]::Unescape('...\uXXXX...');②场景 YAML 里中文是\uXXXX转义,普通文本 grep 搜不到中文节点名。 - 真实运行时日志(第 34 轮的关键证据源):
$env:LOCALAPPDATA\Unity\Editor\Editor.log(UTF-8,PS 5.1 要Get-Content -Encoding UTF8再过滤)。⚠️ Debug.Log里的多行文本会被拆成多行,grep 时别漏续行 ——ClientUiTrace.Click的命中层级/接收组件就是续行,漏掉它们就等于没读到证据。用它比对真实时序,可直接判定“某方法到底有没有被调用”,比读代码推断可靠得多。 ⚠️ verify-scene-facts.ps1的盲区:只解析场景 YAML,看不到 prefab 实例内部的组件与名字(HeroSubPage的英雄卡模板就是 prefab 实例,其ClientHeroCard不会被列出)。凡涉及 prefab 实例的结论,必须用运行日志或 Inspector 复核,别据此下断言。- 批处理日志统一在
Logs/。
2026-09-20(第三十六轮 · 清小项:待办 5 / 6 / 8):
负责人先选
ActivityPage,但只读取证发现它行为已经正确:ClientActivityPage.ApplyTask用binding.Root.SetActive(exists)按GetActivityTasks()条数隐藏多余卡片,奖励槽同样按data.Rewards.Count隐藏多余项 ⇒ 已满足“实例数恒等于数据条数”(场景烘池子 + 运行时隐藏)。做的话属纯结构收敛且要动不可逆的场景,遂改先清小项。① 待办 5 —— 商店卡面角标语义 = 售价(负责人明确)。取证:
数量角标全项目无任何代码引用(纯静态装饰),ClientShopPage只写道具名称。全场景 65 个该节点,全在ActivityPage(60) /MailPage(5);商店卡下那份只读工具看不到(道具卡牌prefab是 prefab 实例 → 工具盲区),故接线做成容错:Find深搜(运行时能穿透 prefab 实例)+ 节点自身与子节点都无文本则静默跳过。已接入两条路径(模板 + 内联回退)。⚠️ 关键区分:同一张道具卡上的道具数量才是“数量”语义(ClientActivityPage绑的就是它),与数量角标是两个不同节点 —— 本次只动商店。② 待办 6 ——
_TEMP_GuideMarker:只删节点没用。RepairAll是幂等的,只要创建代码还在(第 1290 行)就会把节点重新加回来。已删创建代码块并留注释;场景里那个节点仍在ClientShell.unity,删除属场景写入,待负责人确认后单独执行。③ 待办 8 —— 调试诊断已清:全部诊断都走
ClientUiTrace,其Line/Warn/Click与ClientUiClickTracer都检查总开关 ⇒Enabled由true改false一行静音(可见性诊断 / 栈快照 / 显隐 / 路由 / 导航 / 点击),调用点全部保留,改回true即可复查。另移除ClientHeroPage每次RefreshCards都打的“已解锁 N / 共 M”日志(控制台第二大噪声源)。 至此噪声源清完:[UI追踪][性能]+场景规模(第 34 轮)+ 全部[UI追踪](本轮)+ 英雄页刷新日志(本轮)。④ Roslyn 三目标 0 error(
Logs/verify-compile-smallitems.log)。⑤ 工具增强:
Logs/verify-scene-facts.ps1新增「任意页面重名兄弟组扫描」(已函数化,覆盖 ProfilePage + ActivityPage)与「按名查节点全路径 + 分页计数」,证据落Logs/verify-inline-lists.txt、Logs/verify-node-lookup.txt。
2026-09-20(第三十五轮 · HeroPage 整页验收通过 + 定稿清理):
负责人确认:“可以,完美实现” —— 详情只读(BUG-017 根因修复)与升级按钮(BUG-016)均通过,页签选中态此前已通过。
HeroPage(含详情页)整页验收完成,按 §11 记入“已完成并经负责人验收”。① 只读范围纠正(负责人明确):只读仅作用于装备槽 + 升级按钮;天赋/秘技/终结技三个 Toggle 不受限制,任何时候都可切。此前把三个 Toggle 一并
interactable=false属超范围实现,已撤除(第三十四轮 ⑦ 已记录)。注意Assets/Client/MODULE.md第 254 行的权威表述本来就是“装备栏与升级按钮不可交互” —— 是代码超出了文档约定。② 定稿清理:为复测临时加的
详情页升级按钮 onClick 已装配:…状态量日志已删除,未留在定稿代码里。(当时的另一条升级按钮被点击:hero=…实际并未写入,故无需处理。)RequestUpgrade/BindControls已恢复原形,仅保留 BUG-016 的名字回退。③ Roslyn 三目标 0 error(
Logs/verify-compile-final.log)。本页至此无待验证项。④ 遗留(未做,见待办):其余页面列表收敛、商店角标语义、
_TEMP_GuideMarker、ClientFormationPage._slot/_status、调试诊断总清理、board_*工具缺陷。下一个页面待负责人指定。一个值得复用的方法论:本轮两次“看起来是 UI 问题”的卡点,最终都靠读真实日志时序(
Editor.log)而不是读代码推断定位 —— 一次是Show()从未被调用,一次是“日志那次点击发生在修复之前、根本不构成检验”。没读到时序就不要下结论。
2026-09-20(第三十四轮 · 项 1/项 3 同源根因:
Show()从未被调用 + 关掉性能探针):负责人反馈:项 2(页签选中态)已解决;项 1(详情只读)与项 3(升级按钮)没有。据此按 §12.5“修复完全不产生可观察变化时,先怀疑打在了不参与结果的维度上”停线取证,不再换同类改法试。
① 关掉性能监测日志(负责人要求):
ClientUiPerfProbe._enabled默认true → false。EnsureDiagnostics是AddComponent运行时补挂、场景里没有该组件(按 guid 核对命中 0 处),故改字段默认值即生效。 顺带:场景规模:活跃 GameObject=…那 187 行噪声出自同一个Update里的_countSceneScale分支,一并消失。② 不再猜,直接读
Editor.log的真实时序:[1940] 英雄详情只读=False…出现在场景启动绑定时,而[2056] 点击图鉴卡 → [2059] Open(HeroDetail)之后再没有只读=日志 ⇒Show()没被调用。 (上一轮把这条False读成“负责人点的是已解锁英雄”,是误判。教训:日志要连时序一起读;且Debug.Log的多行文本会被拆成多行,漏读续行等于没读。)③ 点击追踪器直接给出被点对象:命中
HeroPage英雄/GuideSubPage/…/英雄卡Item_Instance/Mark(Mark=未解锁遮罩)⇒ 被点的确实是未解锁那张卡,却走成了“已解锁”路径。 同时排除下标错位:ClientHeroCardList.Show用int index = i逐次捕获,unlockedOf(items[i])与onClick(index)同源同序,实例数恒等于数据条数。④ 根因(BUG-017):
ClientUiNavigator.OpenHeroDetail在Open(pageId)成功后查Fallback(HeroDetail),而Fallback只查_pageById,该表只收录ClientUiPage。只读场景核对:全场景仅 1 个ClientUiPage(PagesLayer/MainPage主页,pageId=0 Home);弹窗登记在ClientPopupService._popupById,从不进_pageById⇒ 恒null⇒ 提前return。 于是未解锁只读不生效(页面停在启动那次SetReadOnly(false))、_currentHero恒为null(升级按钮即便装上 onClick 也会在开头return)—— 两项一起“没有”,正是同一个所有者缺陷(§12.4)。⑤ 修法(纯代码,未写场景):
ClientPopupService新增GetPopup(ClientUiPageId)(注册表归它所有,就该由它回答“pageId 对应哪个节点”);OpenHeroDetail改为先向弹窗服务取节点再Show,保留Fallback作为兼容路径。另加两条状态量日志(onClick 已装配/升级按钮被点击 hero=…)供复测核对,定稿前随待办 8 一起删。Roslyn 三目标 0 error。⑥ 工具局限(重要):
verify-scene-facts.ps1只解析场景 YAML,看不到 prefab 实例内部的组件与名字(HeroSubPage的英雄卡模板正是 prefab 实例),一度与日志英雄卡列表=True矛盾。不要用工具的“没扫到”去否定运行时的“确实存在”。⑦ 撤回一处超范围实现(负责人纠正):
SetReadOnly里曾把天赋/秘技/终结技三个 Toggle 一并interactable = false。负责人明确:只读只作用于装备槽与升级按钮,三个 Toggle 任何时候都可切。该三行已撤除(Assets/Client/MODULE.md第 254 行的权威表述本来就是“装备栏与升级按钮不可交互”,是代码超出了文档约定,不是文档错)。教训:验收条件要以负责人原话为准,别把“我认为更合理”的约束塞进需求。
2026-09-20(第三十三轮 · 两项待验证静态核对通过 + 修掉 BUG-016):
① 新增只读场景核对工具
Logs/verify-scene-facts.ps1→Logs/verify-scene-facts.txt:直接解析ClientShell.unity的 YAML 重建节点树(用m_Children还原兄弟顺序、按Button.cs/Toggle.cs的 GUID 数组件、读 Animator 的 controller 参数、读Button.m_OnClick的m_MethodName)。不需要 Unity、不写任何文件,Unity 开着也能跑 —— 正好补上 §12“验证结果而非调用”里最缺的一环:在麻烦负责人 Play 之前先证伪“接线其实没接上”。 注意:本机pwsh实为 Windows PowerShell 5.1,脚本必须纯 ASCII —— 含中文的 UTF-8 无 BOM 脚本会按 ANSI 解析并报Missing closing '}';脚本内中文节点名一律用[regex]::Unescape('...\uXXXX...')字面量。另外场景 YAML 里中文是\uXXXX转义,普通文本 grep 搜不到中文节点名(这也是之前几次“搜不到就以为不存在”的陷阱)。② 待验证 1(详情只读)静态通过:
upCanvas直接子节点实测为upImage | 立绘 | left | right | Panel | Panel (1) | 垂直Panel | 卡牌信息Canvas;Panel内 2 个Button(Bottom1/Bottom2)、Panel (1)内 2 个(Bottom3/Bottom4),根下前往获取+已满级Button自带Button⇒ SetReadOnly 恰好作用于 5 个,与日志期望的已作用于 5 个按钮(panel=2 / panel(1)=2)完全吻合。详情页内 3 个 Toggle =天赋Toggle/秘技Toggle/终结技Toggle。③ 待验证 2(页签选中态)静态通过:
英雄Button/图鉴Button均m_Transition=3(Animation);英雄Button.controller/图鉴Button.controller各含全部 5 个 trigger(Normal/Highlighted/Pressed/Selected/Disabled,均m_Type: 9)⇒DriveTabAnimator的ResetTrigger/SetTrigger全部命中真实参数,不会报 “parameter does not exist”。⚠️ 中途误报过一次,已自我推翻:第一版解析器在m_Type:行就break,只读出 1 个参数Normal,差点把“选中态不可能生效”当结论上报;回到 controller 原文的m_AnimatorParameters段核对后推翻 —— 工具本身也要被验证,不能只信工具的输出。④ 新发现并修掉 BUG-016:同一份场景事实暴露出
前往获取Canvas全场景 0 个节点,而EnsureBound正是从它取容器 ⇒_upgradeButton恒为null⇒BindControls里的onClick从不装配,已解锁英雄点该按钮毫无反应(场景侧该按钮m_MethodName条目数实测 = 0,确无持久监听)。上一轮只给SetReadOnly补了名字回退,漏了这条绑定路径。已在EnsureBound补上与SetReadOnly同名的回退(同一按钮),纯代码、未写场景,Roslyn 三目标 0 error。
2026-09-20(第三十二轮 · 第 5 步完成:详情页只读):
ClientHeroDetailPage新增SetReadOnly(bool)+IsReadOnly,并在Show(hero, illustration)里_currentHero = hero之后按hero.IsOwned自动判定:SetReadOnly(hero == null || !hero.IsOwned);放在 Show 里而不是让各调用方自己传 —— 这样任何入口(英雄页 / 图鉴页 / 未来的其它入口)行为天然一致,符合负责人"这是点击卡牌进入详情页的通用逻辑"的要求。
只读影响范围(只动交互,不动视觉/排版/显隐):
_equipmentButtons(装备栏槽位,对应upCanvas/Panel、Panel (1))、_upgradeButton(前往获取+已满级Button,语义是"获取技能/天赋升级材料")、_talentToggle/_secretToggle/_ultimateToggle。 幂等,并在_upgradeButton装配之后再套用一次 —— 因为首次Show时按钮引用可能尚未装配好。 日志打印英雄详情只读=?(装备栏 N 个;升级按钮=?),便于核对。已完成的 HeroPage 五步:① 取证 ② 角色/卡牌脚本解耦(
ClientHeroCard/ClientHeroCardList)③ 子界面拆分(HeroSubPage/GuideSubPage)④ 子页切换 + 进度 + 页签 ⑤ 详情只读。 遗留:① 若锁定英雄的装备栏仍可点,看日志里"装备栏 N 个"是否为 0 —— 为 0 说明该列表在别处装配,需再查;②_TEMP_GuideMarker临时标记待定稿时删除;③ 列表收敛其余页面(内联列表 49 处)仍待推进。
2026-09-20(第三十一轮 · 进度格式修正 + 页签 Animator 驱动 + 网格对齐):
① 卡牌网格对齐已修(场景):
HeroSubPage/GuideSubPage的 Content 上GridLayoutGroup.childAlignment由 MiddleCenter → UpperLeft。根因:默认 MiddleCenter,子节点未填满时整组居中,故只有 1 张卡时跑到中间。改后卡片固定在左上第一格(背包式)。负责人已验证网格位置 ✓② "总英雄数量不显示" = 格式问题,不是节点问题。只读取证(审计【八】新增
DumpTextNode)读出两个文本的原始设计文案:已收集进度='55'、总英雄数量='/99'(自带斜杠!) —— 设计意图是55/99。 而代码写的是"1"与"2",把斜杠覆盖掉了 → 显示成12,看起来像"总数没显示"。 修复:_totalHeroCountText.text = "/" + 总数。(节点本身 active/白色/字号 26 一切正常,接线也正确 —— 诊断日志此前已证明值='2' active=True。)③ 页签选中态改为直接驱动 Animator:负责人确认"只有 pressed 和 selected 是黄色,其余为灰" → 说明用的是 Button 的 Animation 过渡(Unity 标准 trigger:
Normal/Highlighted/Pressed/Selected/Disabled)。只设EventSystem选中对象不够 —— 被点过的按钮会停在 Pressed 状态,于是两个页签同时呈黄色。现改为DriveTabAnimator()显式重置Pressed/Selected/Normal/Highlighted后按需SetTrigger("Selected"|"Normal")。下一步(第 5 步,负责人已要求执行):
ClientHeroDetailPage.SetReadOnly(bool)—— 未解锁英雄进详情时upCanvas/Panel、Panel (1)装备栏与前往获取+已满级Button不可交互。开工前需先读ClientHeroDetailPage.cs(该类含 15 个节点引用,不能凭猜改)。
2026-09-20(第三十轮 · 修掉"两条卡牌路径并存"):
负责人反馈:英雄子页有 2 张卡仍显示
锁Image与编队队内编号Image;两个页签看起来都是选中态;点任意卡都能进详情但不知有无权限区分。① 已修(根因,日志确证):
[Client] 英雄卡:需要 2 张,容器内既有克隆体 3 个...是旧方法EnsureTemplateInstances的日志 —— 说明第 4 步之后新旧两条路径同时运行。旧路径生成的克隆体从不调用Apply,因而保留模板默认状态(模板里锁Image、编队队内编号Image默认激活)→ 就是那 2 张"带锁和编号的多余卡"。 修复:EnsureBound()的模板分支不再调用EnsureTemplateInstances,卡牌统一由ClientHeroCardList管理。(纯代码,编译 0 error。) 数据侧经日志确认无误:已解锁 1 / 共 2。② 待负责人提供信息:两个页签的选中态。已改用
EventSystem.SetSelectedGameObject驱动 Button 内置Selected状态(并删掉了会盖住它的interactable=false)。但截图显示两个页签都呈黄色底框 —— 需确认:黄色是否本就是 Normal 态?若要可靠表达"当前页签",需知道其 Animator 参数名(bool/trigger)或 clip 名,我直接驱动 Animator。③ 尚未实现:详情页的未解锁只读(装备栏与
前往获取+已满级Button不可交互)属第 5 步ClientHeroDetailPage.SetReadOnly,本轮未做。"点任意卡都能进详情"是符合规格的(未解锁英雄也可进详情,只是只读)。
2026-09-20(第二十九轮 · 页签选中态改用内置机制 + 修掉"静默接线失败"):
① 页签选中态:删掉
interactable写法,改用 Unity 内置 Selected 负责人截图显示英雄Button是Transition = Animation且配了Selected Trigger = Selected—— Unity 的 Button 天生就有 Selected 状态,由EventSystem.current.SetSelectedGameObject()驱动。已改为切换子页时把对应按钮设为 EventSystem 当前选中对象,直接播放负责人自己配的动画。 同时删掉上一轮的interactable = false—— 它会让当前页签进入 Disabled 状态、反而盖掉 Selected 动画(错误做法)。 并说明:_heroTabSelected/_guideTabSelected是GameObject字段,拖.controller资源进不去;且根本不需要它们(留空不影响任何逻辑)。② 修掉一个"静默接线失败"(重要):
_ownedProgressText/_totalHeroCountText的字段类型是TMP_Text,而我传的是节点的Transform→ 类型不符,Unity 静默拒绝赋值:日志打印"已接线=True",场景里却始终fileID=0(负责人正是因此看到 Inspector 为 None)。改为传GetComponent<TMP_Text>()后修复。 验证方式已改为直接读场景文件(_ownedProgressText fileID=4454792166064425531、_totalHeroCountText fileID=483668028028388863)—— 不再只凭日志里的非空判断。这才是 §12"日志要打印状态量"的完整含义:要验证结果,而不是验证调用。场景接线现状(读场景文件确认):
_heroSubPage/_guideSubPage/_heroTabButton(英雄Button)/_guideTabButton(图鉴Button)/_ownedProgressText/_totalHeroCountText六项全部非 0 ✓下一步(第 5 步):
ClientHeroDetailPage.SetReadOnly(bool)。
2026-09-20(第二十八轮 · 第 4 步:两个子页打通(代码 + 接线)):
关键发现:
ClientHero.IsOwned就是解锁状态字段(ClientModels.csL32-41,另有HeroId/Name/Element/Level/StarLevel/CombatPower)。代码(三目标 0 error):
- 新增
OpenHero(ClientHero, Sprite)—— 按对象直接开详情。原因:原OpenCardByIndex用heroes[cardIndex % heroes.Count]映射全表,而英雄子页只显示已解锁、图鉴子页显示全部,两表长度与顺序不同,共用同一下标必然错位。OpenCardByIndex改为委托给它,旧入口(SelectOwnedHero/SelectLockedHero)不受影响。RefreshCards()重写:改用ClientHeroCardList。英雄页 = 仅IsOwned;图鉴页 = 全部且按IsOwned设锁+遮罩(两者由ClientHeroCard同步)。每个子页各自一份"容器 + 模板"的列表实例(复制GuideSubPage时其内部也带了模板,互不干扰)。- 新增
SwitchSubPage(bool)/ShowHeroSubPage()/ShowGuideSubPage()/ApplySubPageVisibility()/RefreshProgress();OnPageRefresh里新增BindTabs()(RemoveListener再AddListener,防重复叠加)。- 进度写入
已收集进度(已解锁数)/总英雄数量(总数)。- 页签选中态:
_heroTabSelected/_guideTabSelected留给负责人拖入他自定义的 animation 状态节点(代码只按需显隐),同时用interactable表达"当前页签不可再点"。场景接线(
Logs/wire-progress.log,8 处变更):_heroSubPage=HeroSubPage、_guideSubPage=GuideSubPage、_heroTabButton=英雄Button、_guideTabButton=图鉴Button、_ownedProgressText=已收集进度、_totalHeroCountText=总英雄数量。实测两个进度文本均为TextMeshProUGUI,与字段类型TMP_Text一致,故直接接线(未凭猜测声明类型)。待负责人做:把页签的 animation 状态节点拖到
_heroTabSelected/_guideTabSelected(留空也能跑,只是没有视觉选中态)。 下一步(第 5 步):ClientHeroDetailPage.SetReadOnly(bool)—— 未解锁英雄进详情时,upCanvas/Panel、Panel (1)装备栏与前往获取+已满级Button不可交互;已解锁则全可交互。
2026-09-20(第二十七轮 · 第 3 步:两个子界面已拆开):
Logs/create-guidesub2.log,5 处变更,批处理正常结束:middleCanvas→ 重命名为HeroSubPage(英雄子界面);由它复制出GuideSubPage(图鉴子界面),并加临时视觉标记_TEMP_GuideMarker(紫色半透明块 + 文字,定稿时整体删掉)。 场景已备份Logs/ClientShell.before-guidesub.unity.bak。过程中踩到并已修复的坑:临时标记最初把
Image与TextMeshProUGUI建在同一 GameObject 上 → 报Can't add 'TextMeshProUGUI' ... because a 'Image' is already added,抛异常导致批处理中止、场景未保存。已改为 Image 作底、TMP 作子节点(这也是 UI 的标准搭法)。顺带做了两处"防改名"加固:①
WireHeroCard改为用FindObjectsOfType<ClientHeroCard>定位模板,不再依赖路径;②ListTargets里 HeroPage 的容器路径同步改为HeroSubPage/MiddleCanvas/...。遗留(无害):本轮日志有
未找到列表容器,跳过收敛:HeroPage英雄/HeroSubPage/...—— 因为ConvergeKnownLists排在改名之前执行,当时节点还叫middleCanvas;下次运行路径即匹配,无需处理。下一步(第 4 步):
ClientHeroPage维护"当前子页"(方案 A),HeroButton/GuideButton选中态驱动HeroSubPage/GuideSubPage激活;卡牌生成改用已写好的ClientHeroCardList;写已收集进度/总英雄数量(路径HeroSubPage/upCanvas/底框Image/)。英雄页只显示已解锁;图鉴页显示全部并按解锁状态设锁Image+Mark。
2026-09-20(第二十六轮 · 英雄卡牌解耦:独立脚本 + 模板接线完成):
背景:负责人指出"英雄卡牌的各个接口逻辑应该单独写几个脚本来管理",并确认命名用英文、
HeroSubPage/GuideSubPage方案选 A(ClientHeroPage维护当前子页,两子页共用同一套卡牌逻辑)。取证(只读,审计【九】):卡牌模板
英雄卡Item实测子树含品质底框Image/品质Image/属性图标Image/卡牌名称Image/立绘Image/LV+等级 image/Lv-Image(inactive)/等级-Text(TMP, inactive)/垂直星星Panel+星级图标Image×5/编队队内编号Image+编号数字/Mark(inactive)/锁Image,根自带Button。注意:模板里没有任何"名称 Text"节点 —— 而旧代码找的是卡牌名称与Text (TMP),两个都匹配不上,故名称与等级从未被写入(卡面一直是美术占位字)。负责人确认:① 允许新建一个 TMP 名称节点;②
Mark就是未解锁遮罩,且必须与锁Image同步出现/消失;③编队队内编号Image只在FormationPage编队显示,其它场合不显示。新增脚本(纯代码,编译三目标 0 error):
Assets/Client/Runtime/UI/ClientHeroCard.cs—— 英雄卡牌的唯一管理者(名称/等级/立绘/锁/遮罩/编队编号/点击)。刻意不依赖ClientHero,Apply只收基础类型,便于任何列表复用。内置两条约束:锁与遮罩同步、编队编号默认强制隐藏(仅SetTeamBadgeVisible打开)。Assets/Client/Runtime/UI/ClientHeroCardList.cs—— "1 模板 + N 实例"管理器,Show(items, nameOf, levelOf, unlockedOf, spriteOf, onClick)。实例数恒等于数据条数,每次 Show 重新对齐,从根上杜绝 2→4→6 累积。场景写入(
Logs/wire-hero-card.log,5 处变更):在卡牌名称Image下新建 TMP 节点卡牌名称;给英雄卡Item挂ClientHeroCard;接线全部字段 ——立绘=立绘Image 名称=卡牌名称 等级=等级-Text 锁=锁Image 遮罩=Mark 编队编号=编队队内编号Image Button=有,_levelDecorations=[Lv-Image]。下一步:第 3 步 ——
middleCanvas→HeroSubPage重命名、复制出GuideSubPage(含临时视觉标记);随后第 4 步子页切换/页签选中态/进度文本,第 5 步详情页SetReadOnly。
2026-09-20(第二十五轮 ·
HeroPage英雄取证 + 修掉卡牌累积缺陷):取证结论(
Logs/hierarchy-audit.txt第八节,只读):场景是干净的 —— 卡牌容器middleCanvas/MiddleCanvas/Canvas/Scroll View/Viewport/Content子节点=1(仅禁用的英雄卡Item模板),全页含"卡牌"的节点只有 1 个。故负责人报告的"4 张 / 6 张"全是运行时累积。 根因(已确证):ClientHeroPage.EnsureTemplateInstances()只按_cardBindings.Count < needed判断、从不清理容器内已生成的克隆体;而UnbindCards()会清空_cardBindings却不销毁克隆体 → 每进出一次多生成一轮 → 2 → 4 → 6 累加,且旧克隆体点击下标越界(表现为"只有某一张能进详情")。这是第二十四轮收敛引入的缺陷。 修复(纯代码,编译三目标 0 error,无需重启 Unity):改为"清空绑定 → 收集容器内非模板既有克隆体 → 按需复用 → 不足才新建 → 多余隐藏",并输出需要 N 张 / 既有 M 个 / 已绑定 K 张便于核对。另两项取证(待负责人回答):①
Background根下那个已是全屏拉伸((0,0)-(1,1)offset 0),另有同名的middleCanvas/Background(490×508 居中固定)——"垂直拉伸不够"指哪个未定;②upCanvas数值合理(锚(0.5,1)、距顶 26~140),"初次位置不对"疑为首次激活布局未重算(待确认是一瞬恢复还是持续错)。下一步(负责人已批准):复制
middleCanvas建图鉴子界面(要有视觉区分、注册进代码、重新命名整理结构),并做英雄/图鉴按钮的选中态 + 子界面切换。(Background/upCanvas两项经负责人微调后已确认"完美"。)
2026-09-20(第二十四轮 · 列表收敛第 3 页
HeroPage英雄落地):负责人指示"继续列表收敛",据此打开
ListTargets中HeroPage英雄的验收闸门(Approved: false → true)并执行。Logs/converge-hero.log,共 12 处变更: 删除 7 张内联角色卡牌Button-final 1→ 保留 1 张重命名为英雄卡Item并禁用为克隆源 → 写入ClientHeroPage._cardTemplate/_cardListRoot。体检复验:
HeroPage英雄节点 190 → 57、交互节点 22 → 15、根尺寸全屏拉伸 ✔;全场景内联列表 57 → 49 处。 顺带修掉一个真实缺陷:旧RefreshCards用heroes[index % heroes.Count]取模填充 —— 8 张卡重复显示同样 2 个英雄;模板化后卡片数 = 英雄数,重复消失。AcceptanceNotes里那条"待批准"的过期说明已同步更新。已模板化 3 页:
ShopPage商店(130→46)、MailPage邮件(263→63)、HeroPage英雄(190→57)。 剩余内联列表 49 处,按体量:ProfilePage个人中心12、ActivityPage活动12、FormationPage编队12、Player lineup7、RankPage排行榜2、Email Details Page(Have)1、HeroDetailPage英雄详情主页1 等;星级图标Image×175 属固定展示、不得模板化。 注意:HeroPage英雄的场景写入待负责人在 Unity 里 Play 验收(§11:验收前不标"已完成")。
2026-09-20(第二十三轮 · 分辨率适配专项完成并经负责人验收):负责人确认"改完了,已验收"。本轮专项共落地如下,全部有日志与体检证据:
# 内容 证据 ① 清除 123 处非根画布 CanvasScaler(12+111,首轮漏删因两套判定口径不一致)Logs/apply-123.log;体检复验"✓ 无"② ClientCanvas:matchWidthOrHeight 0.5→0(按宽匹配)、pixelPerfect true→falseLogs/apply-123.log③ 12 个全屏型页面根+背景铺满;5 个底栏横向铺满 Logs/apply-123.log、add-4-pages.log④ 商店:标题换父级到页面根+贴顶、顶栏贴顶并对齐标题下、底栏铺满、水晶石纵向贴顶 Logs/shop-bars.log、fix-crystal-anchor.log⑤ 5 处顶部元素纵向贴顶(MailPage/ActivityPage/FormationPage/全图鉴×2) Logs/fix-top5.log⑥ Player lineup还原为面板型 + 护栏(只在仍是拉伸态时还原,绝不覆盖负责人的手工尺寸)Logs/restore-player-lineup.log、fix-top5.log⑦ 顶部区域扫描工具口径修正(名字+锚点+页面已拉伸 三项同时成立;打印真实锚点),复验 ✓ 未发现 Logs/hierarchy-audit.txt第七节确立的通用口径:贴哪条边用哪条边的锚;要铺满哪个方向用该方向的拉伸锚;纯背景
(0,0)-(1,1);居中内容不动。WYSIWYG 前提:Game 视图锁753×1630(或同比例1080×2337)编辑,且在 Game 视图里调。纵向安全区按最矮档 1080×1920(画布高 1339)设计。 四个会打破 WYSIWYG 的坑:再给节点加CanvasScaler;勾Override Sorting;用世界坐标调位置;底图直接拉伸变形(应用 9-slice)。遗留:① 若背景拉伸后变形,需改 9-slice(待负责人指认节点);② 第 (4) 步列表收敛仍停在
HeroPage英雄Approved=false待批;③ 调试诊断(可见性诊断/栈快照/Canvas 链)待稳定后清理;④ 商店卡面"数量角标"语义待确认;⑤board_*工具对D:\unity project\pinball报project_path must be an absolute path,看板未建立。
2026-09-20(第二十二轮 · 5 处顶部元素改贴顶 + 扫描口径修好 + 一处"会覆盖负责人改动"的隐患):
① 5 处顶部区域元素改为贴顶锚(
Logs/fix-top5.log):MailPage邮件/Email Title、ActivityPage活动/task title、FormationPage编队/页面分栏-Image、全图鉴活动/顶部角色-Image、全图鉴活动/task title。手法同水晶石:只动纵向、横向保持、世界坐标回写。 ② 扫描口径已修正并复验:判定恢复为「页面已全屏拉伸 且 名字像标题/栏 且 锚点仍为中心」三项同时成立;报告行改为打印真实锚点(上一版硬编码锚=(0.5,0.5)且漏了锚点检查,产出 15 项假阳性)。修正后复验:✓ 未发现 —— 该类问题已清零。 ③ 修掉一处会覆盖负责人改动的隐患:RestorePlayerLineupRect()原会无条件把尺寸写回752×1630,而负责人已把它手动调成正确的675×1127—— 每次RepairAll都会覆盖掉。现改为只在"仍是拉伸态(锚点 (0,0)-(1,1))"时才还原,绝不强行写尺寸,与尺寸解耦。本轮日志确认护栏生效:未对Player lineup做任何还原动作,负责人的675×1127未被触碰。
⚠️ 又一则同类教训(与上一轮"尺寸不足以判定类型"配套):幂等的"修复"必须区分"我改坏的"与"负责人手动调的"。仅凭"当前值 != 我期望的值"就写回,会把负责人的手工调整当成待修缺陷。判定应基于结构状态(是否仍是我造成的拉伸态),而不是数值是否等于我记的那个值。
2026-09-20(第二十一轮 · 四页验收 +
Player lineup回滚 + 一条判定教训):验收结果:
Email Details Page(Have)、Email Details Page (No)、Success Receipt Interface三页通过 ✓;Player lineup(玩家阵容)负责人判定为面板型,不该全屏拉伸 → 已还原。 回滚(Logs/restore-player-lineup.log,3 处变更):Player lineup从size=(753,565) 锚=(0,0)-(1,1)(拉伸态)还原为752×1630+ 中央锚点(0.5,0.5),并已从FullScreenPopups白名单移除(名单内加了注释说明,防止以后再被加回)。
⚠️ 本轮的方法教训(重要):我把Player lineup加入拉伸名单,依据只是"尺寸 752×1630 等于参考分辨率"。 这个依据不成立 —— 面板型弹窗也可以恰好等于参考分辨率,类型是设计意图,不能仅凭尺寸推断。 这与 §12 已记的"运行时读数不能当布局事实"是同一类错误:用可观测的近似量替代了需要确认的意图。 今后凡判定"全屏型 / 面板型",一律先问负责人,不自行推断。扫描口径已修正(少量 A):
AppendTopAreaAnchorScan的判定从几何位置改为名字(title/bar/标题/栏/顶)。原因:多数弹窗体检时未激活、布局未计算,几何判定产出 41 项噪声(连background都被误判)。该口径会漏掉名字不像标题的节点(如Regular store resource exchange - Crystal stones),故只作低噪声起点,兜底靠负责人逐页验收(B 为主)。尚未运行(需关一次 Unity,避免打断验收)。
2026-09-20(第二十轮 · 水晶石兑换条锚点修正):负责人验收 ①②③ 后反馈"除 1080×1920 右上角外都完美",并定位到节点
Regular store resource exchange - Crystal stones。成因(与商店标题同一类):该节点是
ShopPage商店直接子节点、尺寸 134×40、锚点为中心锚(0.5,0.5)→ 根改为全屏拉伸后随画布高度漂移。只有 1080×1920 明显,因为match=0下画布宽度恒为 753,高度按比例算:1080×1920 → 1339(最矮)、1170×2532 → 1630、1080×2400 → 1673;最矮那档顶部元素被压得最近才暴露。 修复(Logs/fix-crystal-anchor.log,4 处变更):只把纵向锚点改为贴顶y=1,横向锚点原样保留(避免同时改动左右定位把问题挪到别处),并以世界坐标回写保证视觉不跳。通用口径(供后续逐页复核):凡"位于顶部区域"却用中心锚的元素,在根拉伸后都会漂 —— 商店已发现两处(
Shopping Mall Title、本节点)。建议按此模式扫一遍其余 8 页的顶部区域元素。 纵向安全区设计口径:按最矮档 1339 设计 —— 顶部元素向下偏移 ≤ ~130、底部元素向上偏移 ≤ ~160,中间留 ~1050 给内容。
2026-09-20(第十九轮 · ①②③ 全部执行完毕,分辨率适配根因清除):负责人确认"①②③ 都同意,全部都做"。
Logs/apply-123.log,共 134 处变更;场景已备份到Logs/ClientShell.before-canvas-scaler.unity.bak(5.4MB,可回滚)。① 非根画布
CanvasScaler全清:123 处(12+111)。首轮只删 12 处的原因已查明:我的删除用owner.isRootCanvas判定,而体检按"非ClientCanvas自身"计数 —— 两套口径不一致导致漏删 111。统一口径后补齐。体检复验:✓ 无(根画布之外没有自带 CanvasScaler 的节点)。嵌套Canvas本身保留,未改动任何 Pos/Size/锚点。 ②ClientCanvas:matchWidthOrHeight 0.5 → 0(改按宽匹配,参考宽度恒定 753);pixelPerfect true → false。 ③ 9 个全屏型页面根与背景全部改为铺满父级;5 个底栏(Rank/Activity/HeroDetail/Formation/全图鉴)改为底部横向铺满。体检复验:9 页全部[全屏拉伸]✓,面板型页面保持固定尺寸(正确)✓。遗留(新发现):
Email Details Page(Have)、Email Details Page (No)、Success Receipt Interface、Player lineup四页尺寸是 752×1630(等于参考分辨率,即全屏型),但目前仍是固定尺寸 → 同样会露边。它们不在本轮 9 页白名单内,待负责人决定是否一并拉伸。
2026-09-20(第十八轮 · 商店顶/底栏锚点规范化,机械部分完成):负责人确认"标题贴顶、功能栏在标题下方"及分工(我做机械锚点、负责人微调间距)。
结构病因(关键):
Shopping Mall Title实际是Bottom page function bar的子节点(Canvas 链证据),继承了"底部锚"父级的运动 → 在matchWidthOrHeight=0.5(画布高度随比例变化)下与顶部功能栏错位重叠。只改自己的锚点救不了,必须换父级。已执行(
Logs/shop-bars.log,共 6 处变更):①Shopping Mall Title父级由Bottom page function bar移到页面根;② 标题锚点 → 贴顶居中(0.5,1);③Top function bar锚点 → 贴顶居中;④ 功能栏顶边对齐到标题下边缘(位移 140.6,间距留 0,由负责人微调);⑤Bottom page function bar→ 底部横向铺满(原 752 宽 → 1279)。改锚点时以世界坐标回写,保证视觉不跳。加上上一轮:根与background已全屏拉伸(共 3 处)。负责人确认的通用模式(跨分辨率兼容):贴哪条边用哪条边的锚;要铺满哪个方向就用该方向的拉伸锚;纯背景
(0,0)-(1,1);居中内容不动。WYSIWYG 前提:Game 视图锁定到参考比例753:1630 ≈ 1:2.164(建议1080×2337),调的是anchoredPosition/sizeDelta。下一步:其余 8 页(Mail/Rank/Activity/Hero/HeroDetail/Profile/Formation/全图鉴)。审计已给出各页"边缘锚 + 拉伸锚"计数,但尚未列出中心锚子节点的名字 —— 而"看起来贴边、实际是中心锚"正是本次商店问题的成因,需扩展体检先列出各页直接子节点清单,交负责人确认后再批量执行。
2026-09-20(第十七轮 · 全屏适配:商店首例已改):负责人要求"全部都要改,先改商店"。
事实基线(只读体检,
Logs/hierarchy-audit.txt第五节新增):CanvasScaler = ScaleWithScreenSize,参考753×1630,matchWidthOrHeight = 0.5(宽高混合匹配,不是按宽) → 比例一变画布参考尺寸宽高都会变,而各弹窗根写成固定尺寸(商店 752×1527、多数页 752×1630)→ 必然露边。参考分辨率恰好等于MainPage主页的尺寸,说明这些页当初就是按参考分辨率整屏画的,只是写成了固定尺寸。 体检同时给出安全性依据:各页直接子节点绝大多数是中心锚(改根后位置不变);边缘锚的多为顶/底栏(Bottom page function bar、upCanvas、downCanvas),改根后会贴到真屏幕边缘 —— 属期望行为。仅 5 页各有 1 个拉伸锚子节点需单独复核。已执行(商店,
RepairAll日志Logs/stretch-shop.log,批处理退出 0,共 3 处变更):根 ShopPage商店752×1527锚(0.5,0.5)→ 铺满父级;background752×1527 → 铺满父级。 其余子节点(顶/底功能栏、Product page 等)一律未动,底栏会自然贴到屏幕底。 工具已写成通用(StretchFullScreenPopups,白名单 9 个全屏型页面),但本轮由FullScreenPopupsThisRun限制为只跑商店,待负责人验收后放开其余 8 页。 面板型弹窗(购买确认/兑换码/联系客服/订单/发货)明确不改,保持居中面板(此前把成功页误判为"缺全屏"已吃过一次亏)。待确认:① 商店在多种分辨率(1080×1920 / 1080×2400 / 1170×2532)下的表现;②
background那张图能否直接拉伸(不能则需 9-slice 或加可拉伸底色);③MailPage/后退Button(左中锚)、HeroPage/upCanvas(顶锚)移到真屏幕边是否为预期。工具问题(待查):
board_get/board_revision对D:\unity project\pinball、D:/unity project/pinball、D:\unity project均报project_path must be an absolute path,看板未能建立。
2026-09-20(第十六轮 · 弹窗层级问题解决 + 复盘固化):负责人确认"完美效果,满意"。本轮把这次反复修复的经验写入
Assets/Client/MODULE.md§12 诊断与修复纪律(下一条目已改为 §13),并同步交接。本轮实际修复的真根因(两个): ① 层级"跑到商店后面" ——
ClientShopPage.BringToFront()里对item的 Canvas 执行了overrideSorting = true; sortingOrder = ++_nextCanvasSortingOrder;。overrideSorting=true的嵌套 Canvas 完全无视层级顺序、只按sortingOrder排, 于是商店内部的Product page(order 1005)与Activity Mall Page(order 1002) 永远渲染在所有弹窗之上。修复分两处,缺一不可:场景清除这两个节点已存的overrideSorting=true(工具ClearNestedCanvasOverride(),体检确认全场景已无该项), 代码删除运行时重新打开它的那段逻辑。这也解释了此前 4 轮改兄弟序号(SetAsLastSibling、 整体重排栈)为何全部无效 —— 那是不参与排序的维度。 ② 成功页"不铺满 + 点任意处不关闭" —— 同一根因:该页根节点上没有任何 Graphic (普查:根组件只有GraphicRaycaster+ClientUiPopup),矩形其实早已是全屏 ((0,0)-(1,1)、sizeDelta=0)。没有 Graphic 就没有东西铺满屏幕、也没有整屏接点击面。 修复:给根节点补一块全屏Image(半透明黑 alpha 0.6、raycastTarget=true), 同时解决"视觉覆盖"与"点击接收";配合BindSuccessDismissHandlers(给页内每个 Graphic 打开raycastTarget并挂ClientShopCloseOnClick)实现点任意处关闭。复盘要点(已写入 MODULE.md §12):① 排序不由层级单独决定,动手前先打印
Canvas.overrideSorting/sortingOrder;② 运行时读数不能当布局事实(我曾把 Play 中的rect.rect.size=215.9×2219.1当作排版事实,误判成功页为"窄竖带"并据此取得授权改动,实际 场景值是居中 752×1527 —— 布局事实以场景/Inspector 为准);③ 沿"谁能改变这个状态"穷举 (用全局搜索列全写入路径,而非改一处试一次);④ 同一所有者原则(显隐与层级只由ClientPopupService决定,View 不得自行SetActive根节点或改层级 —— 本次三个 bugAwake自隐藏 /Open隐藏下层 /Show越权置顶 同源于"整屏替换"旧语义); ⑤ 反证要当反证(修复完全不产生可观察变化时,先怀疑"打在了不参与该结果的维度上"); ⑥ 日志要打印状态量而非调用成功;⑦ 工作流:纯代码改动不关 Unity(避免每次触发提权 警告打扰负责人),仅场景写入才走关→批处理→重启。遗留:调试用诊断(可见性诊断 / 栈快照 / Canvas 链)与
_nextCanvasSortingOrder未使用 的告警仍在,待负责人确认稳定后一并清理;HeroPage英雄仍停在Approved=false待批;ShopPage商店/MailPage邮件的验收与第 (4) 步后续页面仍按 §11 逐页推进。
2026-09-20(第十五轮 · 验收要点入报告):页面管线受 §11 验收闸门约束(未验收不得推进下一页),本轮不新增任何未审阅的行为改动,只做一件只读、零运行时风险的事:让普查报告输出 ★ 验收要点。
实现(
ClientHierarchyAudit):新增AcceptanceNotes表并在AppendOnePage输出,内容数据驱动(写清运行时预期卡片数来自哪个数据源),让 Play 验收有客观对照口径而非凭印象:ShopPage商店(按GetShopListings()=3生成 3 张、点任意一张应打开购买界面)、MailPage邮件(按GetMails()=2生成 2 张、点卡应选中邮件)、HeroPage英雄(待批准;批准前应仍是 8 张内联卡,正是闸门未触发的证据)。编译三目标 0 error。闸门状态未变:
ShopPage商店/MailPage邮件已写入待验收;HeroPage英雄Approved=false、场景未写入。本轮同样未写入场景。阻断点(连续第四轮):第 (4) 步按 §11 约定必须由负责人逐页 Play 验收后才能推进下一页,故以下两项未答复前无法继续:(a)
ShopPage商店/MailPage邮件的验收结果;(b)HeroPage英雄是否批准执行场景写入(批准后只需把ListTargets中该页Approved改true再跑一次RepairAll,约 1 分钟)。目标保持 active。
2026-09-20(第十四轮 · 实现 MODULE.md §6 模态约定,纯代码、未动场景、未推进任何页面):撤掉全局遮罩后,点击穿透的问题重新变成活的——全屏弹窗打开时主页底部图标仍可点,每点一次就往栈上叠一层,正是之前那个"延迟弹出"现象。全局遮罩曾用来堵这个洞,但它会盖住栈顶弹窗(购买界面点不动)且会残留锁死界面,已作废。正解是逐节点屏蔽射线。
实现(
ClientPopupService):新增_allPopups(CollectPopups时收录全部弹窗,含不参与 pageId 路由的二级弹窗)与_lobbyRoot(PagesLayer的第一个子节点=大厅);新增ApplyModalState()并在ApplyMask()开头调用,逻辑是只有栈顶弹窗可点——其下的弹窗与大厅一律blocksRaycasts=false;SetRaycastBlocked()按需补CanvasGroup并设置,只加交互组件,不新建 UI 节点、不改任何 rect。追踪日志会打印[UI追踪][弹窗] 模态 <路径> blocksRaycasts=True/False。编译三目标 0 error。闸门状态未变:
ShopPage商店/MailPage邮件已写入待验收;HeroPage英雄代码就绪但Approved=false,场景未写入(本轮同样未写入)。全场景内联列表仍为 57 处、HeroPage英雄仍为 190 节点 / 8 张卡。下一步(等待负责人):(a)
ShopPage商店/MailPage邮件的 Play 验收结果;(b)HeroPage英雄是否批准执行场景写入。收到答复前不推进任何页面。
2026-09-20(第十三轮 · 把验收闸门做成结构):负责人要求"每页做完要说明、验收通过才算通过"。复查时发现一个会绕过该闸门的隐患:
HeroPage一旦登记进ListTargets,之后任何一次RepairAll(哪怕是为别的修复而跑)都会顺手删掉它的 7 张内联卡 —— 等于未经确认就执行了场景写入。修复:
ListTarget增加Approved字段作为验收闸门。语义是"登记进白名单 ≠ 允许现在动场景";未验收的页面必须停在false,ConvergeKnownLists()会跳过并打印跳过 X:尚未通过负责人验收(ListTarget.Approved=false)。新增一页的完整流程改为:改代码(含内联回退)→ 编译 → 登记且保持false→ 向负责人说明并取得确认 → 改true→ 跑RepairAll。白名单现状:
ShopPage商店true、MailPage邮件true(二者已执行写入、待 Play 验收);HeroPage英雄false(代码侧已就绪,场景写入待确认)。闸门生效验证(只读普查):
HeroPage英雄仍是 190 节点 / 8 张角色卡牌Button-final 1、全场景内联列表仍是 57 处 —— 与登记前完全一致,证明Approved=false确实没有触发任何场景改动。编译三目标 0 error。下一步(等待负责人):(a)
ShopPage商店/MailPage邮件的 Play 验收结果;(b)HeroPage英雄是否执行场景写入(批准后只需把Approved改true再跑一次RepairAll)。在收到答复前不再推进任何页面。
2026-09-20(第十二轮 · 负责人要求改变交付节奏:一次一页、说明后验收):负责人明确要求"每做完一个页面都要与我解释,我验收后才算通过",并要求不得跨页批量推进。据此:
Assets/Client/MODULE.md新增 §11「交付与验收流程(负责人强制要求)」:① 不得跨页批量推进;② 每页完成必须书面说明(改了什么/依据/影响节点数/如何验证/遗留风险);③ 负责人在 Unity Play 验收通过后才算完成,验收前只能标"待验收",CURRENT_STATE.md不得写"已完成";④ 场景写入不可逆,写入前先说明变化并取得确认;⑤ 页内多个子项仍按一页一验收,不反复打断。当前状态:
- 待验收:
ShopPage商店(130→46 节点)、MailPage邮件(263→63 节点)—— 场景写入已执行,等 Play 验收。- 进行中:
HeroPage英雄—— 代码侧已就绪,场景写入尚未执行。已给ClientHeroPage加模板支持:_cardTemplate/_cardListRoot字段、EnsureTemplateInstances()(按GetHeroes().Count克隆并建CardBinding)、RefreshCards()模板分支(按位取用,不再% heroes.Count取模、超出隐藏),并保留内联回退。编译三目标 0 error。尚未登记白名单、尚未跑 RepairAll。
HeroPage英雄的关键取证:该页 9 个内联容器里只有 1 个是真列表 ——middleCanvas/MiddleCanvas/Canvas/Scroll View/Viewport/Content,角色卡牌Button-final 1×8,GridLayoutGroup cell=204x326 固定列数2;其余 8 个都是星级图标Image ×5(每卡一组 5 星),按约定属固定数量展示、不得模板化。英雄数据仅 2 条,而场景 8 张卡 —— 旧RefreshCards用heroes[index % heroes.Count]取模填充,所以 8 张卡反复显示同样 2 个英雄;模板化后卡片数 = 英雄数,重复问题一并消失。
2026-09-20(第十一轮 · 第 4 步流程固化 + 白名单约束):本轮对
HeroPage英雄做动手前前提确认,得出一个必须固化的约束。发现:
ClientHeroPage确实驱动英雄列表(RefreshCards()读ClientServices.Data.GetHeroes()并遍历_cardBindings),所以它可以模板化——但必须先给 View 加模板生成代码。若先删场景实例、后改代码,页面会只剩 1 个禁用模板,这是可见的功能回归。据此把工具改成声明式白名单:新增
ListTarget结构与ListTargets白名单(登记"页面 / 容器路径 / 项前缀 / 模板名 / 模板字段 / 容器字段"),ConvergeKnownLists()只收敛白名单内的目标,不做"扫描到就收敛"。新增一页 = 先改代码 → 编译 → 登记一行 → 跑RepairAll。同步写入
Assets/Client/MODULE.md§7:收敛一页的四步流程(必须按序)—— ①取证(普查数据对照)→ ②校验前提(容器须自带布局组件;星级图标Image属固定展示不得套用)→ ③先改代码后动场景(含内联回退,否则是功能回归)→ ④登记白名单再执行并用普查核对。已完成项:ShopPage商店(130→46 节点)、MailPage邮件(263→63 节点)。编译三目标 0 error。下一轮:按四步流程做
HeroPage英雄(9 容器 / 190 节点,英雄数据仅 2 条 → 失配最严重)。先给ClientHeroPage加模板生成(含回退),再登记白名单。
2026-09-20(第十轮 · 第 4 步可执行性筛查):在普查工具里新增**"该容器是否有布局组件"判定**(
DescribeLayout),因为ConvergeList会拒绝无布局组件的容器(否则克隆体叠在同一坐标=改变布局),必须先筛出来才知道哪些能安全模板化。筛查结论(关键,决定后续路线):剩余 57 个内联列表容器,100% 自带布局组件 → 全部可安全模板化,0 个需要先改布局。按页面:
FormationPage编队12、ProfilePage个人中心12、ActivityPage活动12、HeroPage英雄9、Player lineup7、RankPage排行榜2、Email Details Page(Have)/MailPage邮件/HeroDetailPage英雄详情主页各 1。这意味着第 4 步不存在"必须先加布局组件"的阻塞,剩余工作是把
ConvergeList扩展到各容器 + 各页 View 补模板生成逻辑,属可批量推进的机械工作。 注意星级图标Image×175 是固定 5 星展示、不是列表,不得套用模板化。进度:全场景内联列表 64 → 57 处;
ShopPage商店、MailPage邮件已完成模板化。编译三目标 0 error。下一轮:按容器清单推进下一页。优先
HeroPage英雄(9 容器/190 节点,而英雄数据只有 2 条 → 失配最严重、收益最大)。
2026-09-20(第九轮 · 第 4 步第二站
MailPage邮件模板化落地 + 工具泛化):先更正上一轮的一处误判:我曾在 CURRENT_STATE 写"
MailPage的邮件卡容器只有ContentSizeFitter、未见布局组件"——这是错的。实测该容器同时有ContentSizeFitter与GridLayoutGroup;6 张邮件卡的 y 坐标为-141.5 / -450.12 / -758.74 / -1067.36 / -1375.98 / -1684.6,步长恒为 -308.62(= cell 283 + spacing 25.62)→ 确为布局组件自动排布,模板化同样不改变既有美术与布局尺寸。工具泛化:把上一轮的一次性方法重构为通用
ConvergeList(containerPath, itemPrefix, templateName, target, templateField, rootField)+ConvergeKnownLists()。新增前提校验:容器若无GridLayoutGroup/VerticalLayoutGroup/HorizontalLayoutGroup则拒绝收敛并告警(避免克隆体叠在同一坐标=改变布局)。这条校验是模板化能否安全执行的关键闸门。
MailPage邮件收敛结果(权威验证,走 Unity 实时对象模型):节点 263 → 63(删掉 5 张邮件卡各自的整棵子树)、交互节点 23 → 8、该页内联列表 7 处 → 1 处。全场景内联列表 63 → 57 处。代码侧ClientMailPage新增ApplyMailCardsFromTemplate()(按_mails.Count克隆、为克隆体绑上SelectMail(index)——场景里的邮件卡此前没有任何点击绑定、超出隐藏、写邮件名),并保留内联回退路径。编译三目标 0 error。工具语义修正:普查"数据对照"节原先对模板模式会误报 ✘(场景只剩 1 个模板 vs 数据 N)。现
AppendPair在nodeCount <= 1时输出✔ 模板模式(场景保留 1 个模板,运行时按数据生成 N 个),并把前缀匹配扩到模板名(道具卡牌/邮件)。进度:全场景内联列表 64 → 57 处(
ShopPage商店与MailPage邮件已完成模板化)。剩余集中在ProfilePage个人中心(26) /ActivityPage活动(15) /FormationPage编队(14) /HeroPage英雄(9) /Player lineup(7) /RankPage排行榜(2) 等,其中星级图标Image×175 属固定 5 星展示、不是列表。下一轮按Logs/list-worklist.md继续。
2026-09-20(第八轮 · 负责人全权授权 · 第 4 步首个"1 模板 + 运行时生成"落地):负责人明确"全权授权",据此执行了首个列表数据化改造。
前提验证(关键,不可跳过):模板生成要成立,容器必须有布局组件自动排列克隆体,否则原有手工摆位的卡会全部叠在同一坐标——那才是真的改布局。实测
ShopPage商店/Product page/展示卡牌Scroll View/Viewport/Content自带GridLayoutGroup(cell 214.2×285.6,固定列数 2),13 张卡原本就是被布局组件排布的 → 改为模板生成不改变既有美术与布局尺寸 ✓场景侧(
ClientShellStructuralRepair.ConvergeShopCardList(),幂等):删除 12 张内联卡 → 保留 1 张重命名为道具卡牌Item、禁用为克隆源 → 写入ClientShopPage._cardTemplate与_cardListRoot。日志Logs/converge-shop.log,15 处变更。代码侧(
ClientShopPage):新增ApplyCardsFromTemplate()(按_listings.Count克隆、按下标绑定、超出隐藏、写入道具名称)与UseCardTemplate判定;BindCards()/ApplyCards()保留内联回退路径,因此场景写入前后都不会出现空窗。权威验证(
Logs/hierarchy-audit.txt,走 Unity 实时对象模型):ShopPage商店节点数 130 → 46、交互节点 21 → 9、该页内联列表已消失;全场景内联列表 64 → 63 处。编译三目标 0 error。顺带修正工具缺陷:普查报告的"数据对照"原先硬编码了商城 13 / 邮件 6,收敛后会失真;现改为从场景实时统计(
FindExactPath+CountChildrenStartingWith),随收敛自动更新。本轮新增的数据源基线(
LocalClientDataService):商城 3 · 邮件 2 · 英雄 2 · 背包 3 · 任务 2 · 公告 2 · 活动 6 · 弹珠 2 · 排行榜[BattlePower/Challenge] 各 5 · 活动任务[Newbie/Advanced] 各 5。→ 不匹配是系统性的(如HeroPage英雄190 节点/9 处内联,数据只有 2 条英雄)。下一轮:按
Logs/list-worklist.md推进第 4 步。注意MailPage邮件的邮件卡容器只有ContentSizeFitter、未见布局组件,需先确认其排布方式再决定是否套用模板生成(否则会叠在一起);其余容器(RankPage/ProfilePage 各 Scroll View、任务卡的道具列表)已确认自带GridLayoutGroup。
2026-09-20(第七轮 · 列表数据化方向确认 + 改造清单产出):负责人确认:"好多 Scroll View 里面的 content 的 prefabs 都是不规范的,后续肯定是要通过数据获取的。"
据此把普查报告归并成可执行清单
Logs/list-worklist.md(12KB / 10 个页面)。归并结论:内联列表 64 个容器 / 约 339 个项对象,但去重后只有 8 种列表项类型 ——星级图标Image×175(35 容器)、道具卡牌prefab×98(18 容器)、角色卡牌Button-final 1×32(5)、任务卡prefabs×12(2)、角色卡牌Button-final×6、邮件prefab×6、玩家战力排行prefabs×5、玩家排行perfabs×5。改造工作量取决于 8 个模板,而非 64 个容器。重要区分:
星级图标Image属于固定数量展示(5 星靠显隐表达等级),不是数据列表 —— 保留节点结构、由代码按等级显隐即可;只有项数随数据变化的才是真列表。这条已写入Assets/Client/MODULE.md§7(含负责人确认语与清单指引)。每页容器分布:
ActivityPage活动12 个/62 项、FormationPage编队12/62、ProfilePage个人中心12/62、HeroPage英雄9/48、Player lineup7/36、MailPage邮件7/36、RankPage排行榜2/10、ShopPage商店1/13、HeroDetailPage英雄详情主页1/5、Email Details Page(Have)1/5。
2026-09-20(第六轮 · 第 4 步第二站
MailPage邮件· 代码侧收敛完成):取证——场景Email come/邮件Scroll View/Viewport/Content下有 6 张邮件prefab,而LocalClientDataService._mails只有 2 条;旧实现的_mailLabels只是个 2 槽数组且在场景里全是空的,_emptyHint/_detail同样为空 → 既写不进邮件名,也管不了另外 4 张卡的显隐。已实施(纯代码,未动任何 anchor / sizeDelta / anchoredPosition):
ClientMailPage新增ResolveCardContainer()(按场景真实路径Email come/邮件Scroll View/Viewport/Content定位,Transform.Find逐级精确名)、ResolveCards()(收集邮件prefab*,找不到容器时明确告警而非静默)、ResolveMissingReferences()(补齐_pageRoot;_emptyHint回退到Default节点,不新增任何节点)、ApplyMailCards()(按_mails.Count控制显隐 + 写入邮件名,卡数≠邮件数时告警)、SetCardText()(同时兼容 TMP 与旧版 UGUI 文本,按场景实际组件取用,避免用可能有误的序列化字段类型要求绑定)。RefreshLabels()与Refresh()改为走上述路径。编译三目标 0 error。遗留:
_mailLabels(Text[],2 槽)已不再被使用,字段保留以免破坏已序列化数据;_detail仍为空(场景中语义不明确的Email Title/.../Email text是否为详情区未确认),已做空判不会抛异常。邮件详情弹窗Email Details Page(Have)/(No)、Success Receipt Interface仍无任何打开逻辑,待负责人确认进入条件与内容。验收方式:Play → 主页 → 邮件。应看到只有 2 张邮件卡(其余 4 张隐藏)、卡面显示"欢迎来到弹珠世界 / 开发期补偿"并带未读圆点与"附件待领取";Console 有
邮件卡已收集 6 张与卡数不一致的告警(预期)。
2026-09-20(第五轮 · 第 4 步首站
ShopPage商店· 代码侧收敛完成):取证先行——LocalClientDataService._shopListings只有 3 条(shop-card-001..003),而场景里ShopPage商店/Product page/展示卡牌Scroll View/Viewport/Content下有 13 张道具卡牌prefab。旧实现BindPrefix(_regular, "道具卡牌prefab", OpenListing)把 13 张全部绑到下标 0..12,而OpenListing有if (index >= _listings.Count) return;→ 10 张卡是死区,且表现为"静默无响应"(与 09-20 日志吻合:点第 5、5、3 张无反应,第 2 张才打开购买界面)。同时RefreshListings()原本完全不碰卡牌节点,卡面文字从未被写入。已实施(纯代码,未动任何 anchor / sizeDelta / anchoredPosition):
ClientShopPage新增BindCards()(按层级顺序显式收集卡牌并逐张按下标绑定)+ApplyCards()(按数据条数控制显隐、把_listings[i].DisplayName写入卡面道具名称,并在卡牌数与商品数不一致时输出告警)。BindPrefix一把梭绑定已移除,RefreshListings()末尾调用ApplyCards()。编译三目标 0 error。本轮未做(受目标约束"不改动既有美术与布局尺寸"):① 页面根仍非全屏拉伸(
ShopPage商店锚点(0.5,0.5)-(0.5,0.5)),需负责人授权后才能改为(0,0)-(1,1);② 13 张内联卡未删成"1 模板 + 运行时生成"(本轮只做显隐控制,删除实例属场景结构修改,待授权);③ 卡面数量角标/数量黑底/道具数量的语义未确认(是售价还是拥有数),未擅自写入。④ 页面根上挂的裸Image依赖未改。验收方式:Play → 主页 → 商店。应看到只有 3 张卡(其余 10 张隐藏)、卡面显示"角色卡牌 1/2/3",点任意一张都能打开购买界面;Console 会输出卡牌数与商品数不一致的告警(这是预期,提示后续改模板生成)。
2026-09-20(第四轮 · 第 3 步完成):重写
Assets/Client/MODULE.md为强制约定(135 新增 / 14 删除,11 个章节)。原文件已过期(称ClientShell.unity为"空场景"、目录描述与实际不符)。新约定覆盖:三层结构(PagesLayer只放大厅;一级全屏界面标_pageId且_routeByPageId=true;二级弹窗不占 pageId)、弹窗根必须全屏拉伸、命名(XxxPage/Content/List/Item/Button/Image;禁跨页关键词、首尾空格、拼写错误、裸Image、指数后缀堆叠)、交互(交互节点必须自带命中面;装饰 Graphic 一律raycastTarget=false,两者均记明"普查现状 0 违规,必须保持的基线")、模态(每页根自带CanvasGroup控制blocksRaycasts;禁止再引入全局遮罩并写明 09-20 的两次故障为据)、列表(只留 1 个禁用模板 + 运行时生成;数量必须与数据条数对应;ContentSizeFitter需单向拉伸锚点)、深度/规模上限(深度 ≤ 8、节点 ≤ 200)、依赖禁止事项、验证方式(编译三目标 0 error / 层级普查自检 / Play 后筛[UI追踪]/ 场景写入走RepairAll且需关 Unity)、待确认项。每条约定都对应普查中的具体数字(64 处内联列表、22/23 非全屏根、5 处拼写错误、3 处首尾空格、18 处同级同名、
ActivityPage活动687 节点/深度 13 等),便于第 4 步逐页对照验收。新发现的文档债:
Assets/Client/UI/下仍有已删页面的子模块文档 ——UI/BackpackPage/MODULE.md(ClientBackpackPage已于 09-18 删除)、UI/BadgePage/MODULE.md(ClientBadgePage/ClientBadgeButton已删);UI/PrimaryPages/MODULE.md、UI/MainPage/HomeDisplay/MODULE.md对应的页面脚本已不再被场景引用。按AGENTS.md§6 的清理要求,需先记录候选项与依据再决定是否移除,本轮未删除。治理覆盖检查:
Runtime/Runtime/UI/Runtime/Services/Runtime/Domain/Editor/UI/Scenes均已有MODULE.md✓下一步(第 4 步 · 按页面逐个收敛,一次一页):建议顺序
ShopPage商店(130 节点/深度 8/1 处内联列表 13 张卡/21 交互)→MailPage邮件(263/12/7 处内联/30 个命名残留)→RankPage排行榜→ActivityPage活动(687/13/15 处)→FormationPage编队→ 其余。每页收敛后由负责人 Play 验收,通过再进下一页。
2026-09-20(第三轮 · 普查报告完成):新增只读工具
Assets/Client/Editor/ClientHierarchyAudit.cs(Menu:Client → 结构修复 → 6. 层级普查报告(只读),批处理Pinball.Client.Editor.ClientHierarchyAudit.RunAudit),报告落盘Logs/hierarchy-audit.txt(26.5KB)。该工具不写入场景。普查结论(2841 个 GameObject):三层结构正确(PagesLayer 1 / PopupLayer 19 / SystemLayer 1)。交互组件 Button=209、Toggle=11、ScrollRect=35、自定义指针处理器宿主=291;Graphic=2559,其中
raycastTarget=true有 2010。好消息(前几轮的修复已生效,两项归零):A. 交互节点命中面来自祖先或缺失 = 0;B. 装饰 Graphic 仍参与射线 = 0。
待收敛的结构问题(按规模排序):① 列表在场景内联展开共 64 处(最大项):
ProfilePage个人中心26 处、ActivityPage活动15 处、FormationPage编队14 处、HeroPage英雄9 处、MailPage邮件7 处、Player lineup7 处、RankPage排行榜2 处、HeroDetailPage/ShopPage/Email Details(Have)各 1 处。典型:MailPage的邮件prefab ×6每个内嵌道具卡牌prefab ×5(共 30 个节点被判定为跨页复制残留)。② 页面规模失衡:ActivityPage活动687 节点/深度 13、ProfilePage个人中心540 节点/深度 11、MailPage邮件深度 12。③ 22/23 个页面根为非全屏(仅Purchase Success Page全屏拉伸)——这是"弹窗没有天然模态边界、才需要外挂遮罩"的量化依据。④ 命名问题:拼写错误 5 处(玩家排行perfabs应为prefab)、名字含首尾空格 3 处(Panel_Personalize␣␣、␣Card info2、challenge␣)、同级同名节点 18 处(大量Image)。⑤Purchase Success Page与Success Receipt Interface交互节点数为 0 —— 前者全屏拉伸且无任何 Button/自定义指针处理器,打开后没有任何关闭手段(与 09-20 日志中Open Purchase Success Page 栈深=2之后从未关闭相互印证);后者同理。正面发现(应保留的设计):多数二级弹窗根自带
CanvasScaler + GraphicRaycaster,即为独立子 Canvas,天然隔离 Canvas 重建,符合最佳实践;后续约定应固化这一点,而不是把 19 个弹窗摊在同一个 Canvas 下。下一步(第 3 步):把层级与命名约定写入
Assets/Client/MODULE.md(该文件当前过期,仍称ClientShell.unity为空场景)。第 4 步按页面逐个收敛,建议顺序:ShopPage商店→MailPage邮件→RankPage排行榜→ActivityPage活动→FormationPage编队→ 其余。
2026-09-20(第二轮 · 方向调整):负责人指出"UI 层级不合理",经证据核对成立,决定停止逐点打补丁,转为结构性收敛。 本次会话暴露的 8 条结构问题(均有证据):① 节点名是复制残留不表意(
RankPage内叫邮件Scroll View、MailPage邮件内嵌道具卡牌prefab、玩家排行perfabs拼写错误);② 容器与视觉不分层,装饰 Image 与交互目标同节点、raycastTarget默认全开(全场景关掉 479 个);③ 交互节点自身没有命中面,17 个 Button(avatar Mask/Avatar)靠祖先的 Image 接收射线;④ 预制体在场景内大量内联展开(全场景 90 个道具卡牌prefab实例,MailPage单棵子树约 200 对象);⑤ 列表节点与数据不对应(商城 13 张卡 vs 更少的_listings,多数卡点了无反应);⑥ 弹窗根节点尺寸非全屏(联系客服Page732×377、ProfilePage733×1300),没有天然模态边界;⑦ 19 个弹窗同挤一个 Canvas,无排序控制;⑧ 页面由复制粘贴产生(联系客服Page上同时挂ClientProfilePage+ClientUiPage)。已执行的处置:撤除全局弹窗遮罩——上一轮新建的
弹窗遮罩节点已验证会造成两个新问题:遮罩会盖住栈顶弹窗(Product Purchase Interface点不动,日志中后续点击全部只命中弹窗遮罩),以及栈未清空时遮罩残留把整个界面锁死。现已删除该节点并清空ClientPopupService._maskRoot,RepairAll中的EnsurePopupMask改为RemovePopupMask。遮罩方案作废,模态改由"每页根自带 CanvasGroup"承担。新的四步计划(负责人确认):(1) 撤掉遮罩 ✅ 已完成;(2) 产出全量层级普查报告(只读不写场景):每页层级深度、节点数、交互节点及其命中面归属、装饰节点、命名异常、数据-节点对应关系;(3) 把层级与命名约定写入
Assets/Client/MODULE.md(页面根命名;Content/List/Item/Button/Image命名;交互节点必须自带命中面;装饰 Graphic 一律raycastTarget=false;每页根自带CanvasGroup由它控制模态;列表由数据生成而非场景内联实例);(4) 按页面逐个收敛,一次一页、每页可独立验收,不改动既有美术与布局尺寸。注意:
Assets/Client/MODULE.md当前仍是过期内容(称ClientShell.unity为"空场景"、目录结构描述与实际不符),将在第 (3) 步一并重写。目标goal-3d2e3b1d已被改写为新四步计划,但当前处于 paused,模型无权 resume,需负责人在 GUI 恢复。
2026-09-20(续 09-18):①
ClientPopupService._popupLayer自动兜底。 日志证实点商城道具卡后Product Purchase Interface确实被打开([UI追踪][弹窗] Open … 栈深=2),但_popupLayer为空导致Open()末尾的SetAsLastSibling被整段跳过,弹窗只能按场景原始兄弟顺序渲染——Product Purchase Interface是 PopupLayer 第 11 个子节点、ShopPage商店是第 4 个,于是购买界面被商店盖在后面,视觉上像"点了没反应/回到主页"。日志中ReturnHome出现 0 次,导航逻辑本身正常。现Awake()在_popupLayer为空时取transform(该组件本就挂在 PopupLayer 上),不再依赖人工拖槽位。09-18 遗留的"商城道具卡未证实"一项就此收口——卡牌 Button 与BindPrefix(_regular, "道具卡牌prefab", …)均已生效。② 全场景射线与显示解耦(负责人明确要求)。 新增
ClientShellStructuralRepair.DecoupleRaycastMenu()(Menu:Client → 结构修复 → 5. 解耦射线与显示(全场景),批处理可用)。规则:自身、或自身到最近 Canvas 之间的任一祖先上存在交互组件(Selectable/ScrollRect/EventTrigger/任何I*Handler自定义脚本)→ 保留raycastTarget;否则关闭。不能按"该节点没 Button 就关"——交互节点的命中面常由子 Image 提供(商城道具卡牌prefab根有 Button 但自身无 Graphic,靠子立绘接收射线后冒泡到 Button)。实测:扫描 2559 个 Graphic,关闭 479 个、保留交互区 1993 个;第二次运行关闭 0 个(幂等)。内置命中面自愈:为 17 个"命中面原本挂在祖先上"的交互节点(全部形如…/avatar Mask/Avatar (Button),Avatar自身无 Graphic)恢复最近可用射线表面(targetGraphic→ 子树首个 Graphic → 最近祖先 Graphic)。最终体检 所有 Button/Toggle 等仍保有可射线表面,0 破损。本操作不修改任何尺寸、锚点、位置与渲染顺序。③ 诊断指标纠正。
ClientUiClickTracer原打印onClick监听数=N,实为GetPersistentEventCount()(只统计 Inspector 持久监听),运行时AddListener永远计为 0 —— 曾误导负责人以为卡牌未绑定。现明确标注为Inspector持久监听=N(运行时AddListener不在此计数)。
2026-09-18(阶段总结 · 交接):目标——修复非战斗客户端 UI 结构,使
ClientCanvas的PagesLayer/PopupLayer/SystemLayer三层分层真实生效,消除双导航器并行、重复ClientUiPageId、页面节点缺失/未注册,并把Assets/Client向 MVC 收敛。架构基线(负责人确认,优先于 HANDOVER_PLAN §3):PagesLayer只留MainPage主页;其余全屏界面全部是PopupLayer弹窗;SystemLayer放加载Page与 Toast/遮罩。执行结果(已落盘并逐项静态复核):
PagesLayer=1(仅MainPage主页+ClientUiPage(Home));PopupLayer=19(9 个一级全屏界面挂ClientUiPopup(路由)+联系客服Page+ 9 个二级弹窗(不路由));SystemLayer=1。全场景ClientUiPage=1、ClientUiPopup=19、ClientHeroDetailPage=1(旧重复实现节点已删,含 64 子节点)、ClientProfilePage=1、ClientPageNavigator=0(类型与组件均已移除)、ClientUiBackButton=13、ClientPopupService/ClientSystemFeedback/ClientShellController/ClientUiClickTracer各 1。已删 7 个孤儿脚本(ClientGachaPage/ClientMarblePage/ClientNoticePage/ClientBackpackPage/ClientHeroEnhancePage/ClientBadgePage/ClientBadgeButton)并整体废弃两个旧 Editor 工具(ClientShellDirectUpdater/ClientShellUiBuilder)。场景修复统一由Assets/Client/Editor/ClientShellStructuralRepair.cs的RepairAll()承担,幂等(重复运行只剩幂等项)。本轮定位并修复的缺陷(均有日志/结构证据):①
ClientPopupService曾实现IClientNavigationObserver,导航器TryOpen打开弹窗后NotifyObservers立即触发自身CloseAll(),导致所有跳转表现为"点了没反应"——已移除该实现,收口职责归导航器Back/ReturnHome。②ClientProfileNavigationController原挂在PagesLayer且Bind()在Start();ProfilePage个人中心迁入PopupLayer后既是"启动即隐藏的弹窗"(Unity 不调用未激活对象的Start),又不在其子树内 → 7 条路由全部失联、面板停在场景初始态。现改为挂在ProfilePage个人中心、Bind()移入Awake()并加!_bound兜底、搜索根改用显式_pageSearchRoot。③ToggleGroup A上原本没有ToggleGroup组件、3 个顶部 Toggle 的m_Group全为 0;且BindNestedToggles只在_pages.Values内找 5 元组,而那 5 个 Toggle 在Panel_Personalize/SubTabBar/Image/Panel→ 全部未绑定。现按名字识别 + 补挂ToggleGroup(AllowSwitchOff=false)+ 写入 3 个m_Group+ 发现范围改为SearchRoot。④ 全场景ClientUiBackButton实例为 0(旧工具找的是不存在的ReturnButton,实际节点叫后退Button/BackoffButton)→ 13 个后退键全部补挂。⑤Panel_Showcase的大铭牌立绘image/铭牌Image渲染在顶部 Toggle 之上并吞掉点击(日志 EventSystem 命中列表首位即该图);曾误用"改渲染顺序"修复并被负责人否决,现改为恢复原渲染顺序 + 只关闭 3 个装饰节点的raycastTarget,视觉零变化。⑥展示卡牌Scroll View 1滚不动是两因叠加:Content 锚点双向拉伸 +ContentSizeFitter两轴均为Unconstrained(等于不生效)→ 已改为(0,1)-(1,1)+pivot(0.5,1)且VerticalFit=PreferredSize。⑦ 主页底部功能图标改为真实节点名(BottomFunctionIcon_Rank/_Shop/_Mail),MarbleButton按负责人确认改指向HeroPage英雄,BottomFunctionIcon绑定联系客服弹窗。⑧ 7 个"页面 → 已迁出弹窗"的序列化槽位由工具自动写入(ClientShopPage×5、ClientRankPage×1、ClientHomePage×1),页面弹窗显隐改走IClientPopupService。⑨ClientBootstrap原会为全图鉴活动节点重新AddComponent<ClientUiPage>,迁移后会造成双所有者——已改为纯依赖注入。验证:独立 Roslyn 全量编译
Assembly-CSharp[Editor]/Assembly-CSharp-Editor[Editor]/Assembly-CSharp[WebGL]三目标均 0 error(脚本Logs/verify-compile.ps1)。场景写入走批处理Pinball.Client.Editor.ClientShellStructuralRepair.RepairAll,逐次日志见Logs/client-structure-repair*.log。新增诊断设施ClientUiTrace/ClientUiClickTracer([UI追踪][点击|导航|弹窗|显隐|路由],默认开启,ClientUiTrace.Enabled=false可静音),已能输出"鼠标点了谁 → 谁接收 → 是否跳转 → 谁改了显隐"的完整证据链。负责人已验收:个人中心(3 主面板 + 5 子 Toggle 互斥、默认子页、后退)通过。遗留风险 / 待确认(明天优先):① 未实测——商城的 13 张
道具卡牌prefab已由工具补Button(ClientShopPage绑定名同时从场景中不存在的展示卡牌Button改为道具卡牌prefab),但静态解析显示这 13 个 Button 块的m_GameObject无法在场景具名对象中定位,推断是 prefab 实例覆盖(未证实)。需负责人 Play → 商店 → 点道具卡实测:能弹购买界面即收口;仍无反应则改为直接给道具卡牌prefab预制体资产加 Button**。②ClientPopupService._maskRoot与ClientSystemFeedback的 Toast 槽位仍为空(弹窗不切遮罩 / Toast 只记警告),需负责人指定节点。③ClientFormationPage._slot/_status未绑定;编队页完整逻辑(3 槽位/4 队伍/队内编号/详情键)尚未实现。④Email Details Page(Have)/(No)、Success Receipt Interface已迁入PopupLayer但代码里没有任何打开逻辑(负责人早前也确认"逻辑好像没实现")。⑤ 任务卡无需补 Button(其子树内已有领取+待完成键Button且ClientActivityPage已绑定RequestClaim;负责人已确认维持现状)。⑥BackpackButton仍会提示 Backpack 未注册(背包页已按负责人要求删除)。⑦Assets/Client/MODULE.md已过期(仍称ClientShell.unity是空场景),需按 AGENTS.md §6 刷新。⑧ClientPageNavigator类型已删,其残留m_Enabled=0组件在场景中已移除(计数 0),如后续再见到需复查。下一阶段:S5 逐页 Controller 抽离(ClientServices.Data调用点需从 View 移出)、S7IClientDataService按域拆分并返回快照而非活列表、A3 为LocalClientDataService纯规则补自动化测试。
2026-09-16:负责人 Play 验证发现活动列表卡片无法点击;确认现有
活动底框prefabs根节点只有 Image、没有 Button,而旧绑定仅处理预挂 Button,导致全图鉴入口事件从未注册。ClientActivityPage.BindSeasonalList现会在运行时为每张现有活动卡补充 Button,以卡片 Image 作为可射线targetGraphic,关闭默认颜色过渡并绑定对应活动索引;不修改或新增场景 GUI 节点。全图鉴页领取素材捕获同步改为页面激活后的延迟初始化,避免 inactive Animator 产生Animator is not playing an AnimatorController警告。独立 Roslyn 全量编译退出码 0;Unity 批处理仍因可见 Editor 占用工程未进入导入,日志Logs/codex-complete-guide-entry-fix-compile.log。待 Refresh 后复验第一张“全图鉴活动”可点击进入详情页。
2026-09-16:已为现有
ClientCanvas/PagesLayer/Complete Guide Event Page全图鉴活动接入运行时控制器,未创建、删除或调整 GUI 节点。页面默认隐藏,活动列表首个本地“全图鉴活动”入口经ClientUiNavigator打开;左下BackoffButton返回活动列表,问号按钮显示初始隐藏的规则弹窗。现有 23 个 Image 均可按枚举槽接收数字图片 ID,6 个 TMP/Legacy 文本均可按枚举槽赋值;进度明确绑定语义正确的进度条底框与其子节点进度条,完成态、领取/待完成素材切换、不可重复领奖和已领取图标复用活动页规则。本地数据服务新增全图鉴活动读取/领奖边界,当前使用 2/2 可领取模拟数据,仅用于演示。Unity 命令行因当前可见 Editor 占用工程未进入导入,日志Logs/codex-complete-guide-event-compile.log;使用 Unity 现有完整响应文件执行独立 Roslyn 编译退出码 0。待负责人 Refresh 后 Play 验证入口、弹窗、进度、领奖和返回;正式活动期数/规则/奖励、图片 ID→YooAsset、服务端持久化及统一 Tips 仍待确认/接入。
2026-09-15:负责人已在 Unity Play 模式完成加载页人工验收,确认
ClientCanvas/SystemLayer/加载Page层级正常,一键 5 秒分段加载演示、SmoothDamp平滑进度追赶和三标点 1→2→3 循环显隐均无问题。本轮标记为“本地加载界面表现闭环完成”;正式 YooAsset/网络加载进度源与数字图片 ID 解析仍待后续接入。
2026-09-15:负责人验证发现一键演示中的插值主要表现为速度差异。原因是旧演示每帧都提交连续线性目标,输入本身已平滑。现将 5 秒演示改为模拟真实加载器的分段检查点(0%、8%、22%、47%、63%、82%、94%、100%),每段只更新一次目标值,由正式
SmoothDamp逻辑平滑追赶,便于直观验证“消除跳变”而非单纯减速。文本差异检查通过;Unity 命令行仍因当前 Editor 占用工程而未编译,日志Logs/codex-loading-stepped-preview-compile.log。
2026-09-15:加载进度由直接赋值改为“目标进度 + 显示进度”平滑追赶。
SetProgress只更新 0~1 目标值,单一协程通过Mathf.SmoothDamp和Time.unscaledDeltaTime更新Image.fillAmount,默认平滑时间为 0.15 秒;连续到达的分段进度不再瞬间跳变。Begin/Complete使用立即赋值保证起点和 100% 无拖尾,一键 5 秒演示自动复用该插值逻辑。文本差异检查通过;Unity 命令行编译因当前 Editor 占用同工程未进入编译,日志Logs/codex-loading-progress-smoothing-compile.log,待现有 Editor Refresh 后验证。
2026-09-15:加载页新增仅 Unity Editor 可用的一键 5 秒演示。进入 Play 后选中
ClientCanvas/SystemLayer/加载Page,可在ClientLoadingPageInspector 点击“播放 5 秒加载演示”;演示会显示加载页、用非缩放时间将进度从 0% 推至 100%,同时运行三标点循环,结束停在 100%。演示方法使用UNITY_EDITOR条件编译,不进入正式 Player 构建。文本差异和唯一调用点检查通过;Unity 命令行编译因当前 Editor 占用同工程未进入编译,日志Logs/codex-loading-preview-compile.log,待现有 Editor 执行Assets > Refresh后验证 Console。
2026-09-15:负责人复验发现
加载Page既不在PagesLayer也未显示于SystemLayer。查明为上次手工修改大型 Unity YAML 时只将加载页的m_Father指向SystemLayer,但子列表引用被误写到活动页“已领取icon”下。现已删除误引用,并在SystemLayer的m_Children中精确写入加载PageRectTransform;文本检查确认父子双向引用唯一且一致。当前打开的 Editor 需重新打开ClientShell.unity以丢弃内存中的旧层级快照后复验。
2026-09-15:已将负责人新制作的
加载Page从PagesLayer迁移至ClientCanvas/SystemLayer,移除误挂的ClientUiPage/ClientProfilePage、旧IClientResourceLoadSource/独立跳动标点逻辑,以及ClientUiFeedback.SetLoading旧加载遮罩入口。新ClientLoadingPage已绑定背景、Logo、进度底框、进度条、3 个标点和 TMP 加载文本;所有 Image 支持数字 ID 接口,文本支持泛型赋值,进度条按 01 或 0100 从左向右增长,标点按 1→2→3 依次消失后再依次出现。当前打开的 Unity Editor 已对新加载控制器及场景变更自动编译,Tundra build success、运行时和 Editor 程序集均产出;后续删除ClientUiFeedback旧入口的小改动已做唯一调用点静态检查,待 Editor 再次 Refresh。独立命令行 Unity 因同工程被 Editor 占用未进入编译,日志Logs/codex-loading-page-compile.log。待人工 Play 验证进度条和标点时序;正式图片 ID→YooAsset 解析实现仍待接入。
2026-09-14:负责人已完成人工验证,确认
ActivityPage活动本轮大体逻辑无问题:默认新手页、三页互斥、新手/进阶状态隔离、蓝底黄条进度显示、满进度切换领取态、领奖后显示已领取、奖励卡数量保持及底部页签选择状态均通过当前验收。本轮标记为“本地模拟闭环完成”;真实任务持久化、服务端领奖确认、背包/邮件投递、图片 ID→YooAsset 和统一 Tips 仍待后续接入。
2026-09-14:ActivityPage 任务完成态补充真实素材切换。此前进度满仅设置 Button 可交互,并尝试使用尚未接入的数字图片 ID,因此仍显示场景默认“待完成”。现从既有
领取+待完成键Button.controller的Pressed动画捕获“领取底框/领取”两张 Sprite:未满恢复默认待完成图,满进度立即固定显示领取图,点击成功后仍进入已领取图标状态;后续数字 ID 解析器接入后可覆盖该本地素材兜底。
2026-09-14:负责人复验发现完成任务
1/1仍只显示蓝色。原因是黄色进度节点虽然已按 100% 宽度更新,但 Canvas 同级绘制顺序使蓝色底框覆盖在其上。源码已明确调整为“蓝色底框在下 → 黄色进度在上 → 进度数字最上层”,不修改场景保存的节点层级。当前源码时间为 18:14,而 UnityLibrary/ScriptAssemblies/Assembly-CSharp.dll仍为 18:12,证明打开的 Editor 尚未导入此次源码;命令行实例又因同工程被占用而无法代编译。负责人需在现有 Unity 窗口退出 Play 后执行Assets > Refresh(或Ctrl+R),等待 Console 编译完成,再重新 Play 验证。
2026-09-14:根据负责人首轮 ActivityPage 人工验证修正四项行为:场景中命名写反的进度节点已按实际视觉解释为“蓝色
进度条=底框、黄色进度条底框=实际进度”;奖励数据少于现有道具卡数量时不再隐藏任何道具卡牌prefab;页面根直接激活时在OnEnable/Start强制初始化为新手任务;领奖刷新后恢复当前底部页签 Button 的 EventSystem 选择状态,领奖不再退出页签选择动画。ClientBootstrap在场景无有效 Camera 时创建仅清屏的运行时 Camera,避免 Game 窗口透出No cameras rendering,不改变 UI 层级。MSBuild 运行时编译退出码 0;Unity 命令行因当前 Editor 占用工程未进入编译,日志:Logs/codex-activity-page-fixes-compile.log。待负责人重新 Play 验证。
2026-09-14:已按负责人重构后的现有 GUI 重写
ActivityPage活动,并停用ClientShellDirectUpdater的旧活动页生成/筛选路径,未创建、删除或调整 UI 节点。进入页面默认显示新手任务;新手/进阶/活动三页互斥,新手与进阶各有 5 条独立数据和独立领奖状态,多出的第 6 个现有卡槽会随无数据自动隐藏。任务说明、当前/总数、从左向右的离散进度条、奖励道具卡、待完成/可领取/已领取状态已接入;未完成按钮无响应,领取成功后领取 Canvas 隐藏、已领取图标显示,同一数据状态不可重复领取。领奖接口显式支持拒绝/处理中/已发放以及背包/邮件投递渠道;活动卡文本、红点、热门标记和图片均有替换接口。运行时和 Editor MSBuild 验证退出码 0;Unity 2022.3.57f1c2 命令行验证因可见 Editor 占用工程而在导入前退出,日志:Logs/codex-activity-page-compile.log。正式服务端持久化、邮件投递规则、图片数字 ID→YooAsset 映射和 Tips 弹窗仍待接入。
2026-09-14:
HeroDetailPage英雄详情主页的旧空引用逻辑已替换为按现有层级运行时绑定。HeroPage 的 8 张既有卡牌均接入点击入口(双击等同连续点击),打开详情时直接传递被点卡牌的立绘Image.sprite。详情页已提供图片数字 ID、文字、六项属性、立绘左右切换、三页互斥 Toggle、两项升级消耗、材料数量样式、确认升级和装备槽扩展事件接口;默认显示天赋页,Toggle 的 Checkmark 不再被常态自动隐藏。误挂在其它同级页面的旧详情组件会自动停用,不删除其 GUI。开发期本地数据以“养成材料 + 金币”填充两个消耗槽并完成校验/扣除,失败通过TipRequested预留弹窗接入。Unity 2022.3.57f1c2 命令行验证因可见 Editor 占用工程而在编译前退出,日志:Logs/codex-hero-detail-logic-compile.log;补充 MSBuild 对Assembly-CSharp验证退出码 0。负责人已在 Unity 中完成人工验证并确认无报错,卡牌入口与详情页本轮逻辑验收通过。最终材料配方、装备槽动作、图片 ID→YooAsset 映射和 Tips 样式仍待确认。
2026-09-12:Player lineup 的本地模拟阵容卡牌数量已由 5 扩展为 6,与
展示卡牌Scroll View/Content的六个既有卡槽(含展示卡牌plusButton (5))一致;无需调整 UI 节点或布局。命令行 Unity 编译仍因 Editor 占用工程而在脚本编译前退出,日志:Logs/codex-rank-lineup-six-cards-compile.log;待 Editor 自动重编译与人工验证第六张卡牌显示。
2026-09-12:已定位并清理
Assets/Client/animator controller/Battle powerButton.controller的Normal动画片段中的唯一空函数名 Animation Event。该事件会在按钮状态动画播放时触发AnimationEvent has no function name specified!并刷屏;删除后不影响 Normal/Highlighted/Pressed/Selected/Disabled 的既有 Sprite 动画与按钮交互。文本检查确认该控制器已无functionName:;命令行 Unity 验证因 Editor 占用工程未进入导入/编译,日志:Logs/codex-battle-power-animation-event-compile.log,待 Editor 重新导入后确认 Console 不再出现该警告。
2026-09-12:主页实际按钮
BottomFunctionIcon_Rank已接入既有ClientHomePage → ClientUiNavigator → RankPage排行榜导航链;排行榜顶部Bottom page function bar/BackoffButton在未打开玩家阵容时改为明确调用ReturnHome,保证回到主页且清空返回栈。未改动任何 UI 节点、布局或位置。命令行 Unity 编译因当前 Editor 占用工程而在脚本编译前退出,日志:Logs/codex-rank-navigation-compile.log;待 Editor 自动重编译与人工点击验证。
2026-09-12:排行榜旧的三条文本快照模型、
GetRankEntries接口与ClientShellDirectUpdater的旧排行榜生成入口已移除,场景中旧组件的已失效序列化字段也已清理。ClientRankPage排行榜实际节点扫描确认:固定背景区、Battle Power Ranking、Challenge List、Player lineup均已在场景中;新实现仅通过节点名绑定现有 5 条榜单行与 5 张阵容卡,不改变 Prefab、位置或布局。新增本地模拟的分榜单/玩家阵容/卡牌数据边界,以及头像、头像框、徽章、立绘、属性与品质 Sprite-ID 映射接口。命令行 Unity 编译已按流程执行,但工程正被 Unity Editor 实例占用而在脚本编译前退出;日志:Logs/codex-rank-compile.log。待 Editor 自动重编译或释放工程后重验,并人工点击验证榜单切换、查看阵容、关闭阵容和顶部返回。
2026-09-11:为实习开发学习与成果复盘创建本地 Git 快照提交
840fc330(客户端源码、Lua/WebGL/DLL、场景、预制体、工程配置与治理文档;不含图片、音频、模型、材质、字体、动画和资源包)。推送至配置的origin时 GitHub 返回Repository not found;待负责人提供已创建且当前凭据可访问的仓库地址或授予访问权限后重试。
2026-09-10:按负责人要求关闭商城导航诊断输出但保留脚本。
ClientShopNavigationDiagnostics与返回链路仍在,ClientShopPage.enableNavigationDiagnostics默认关闭;后续若需复现,仅在该现有组件 Inspector 勾选此字段即可恢复完整[ClientShop导航诊断]日志。
2026-09-10:商城回归测试日志已核对通过。
[ClientShop导航诊断]连续四次均显示PointerDown → PointerUp → 商城后退 onClick 已触发 → shopSelf=False/shopHierarchy=False/home=True,证明主返回按钮、统一导航与主页恢复完整闭环。Event MallButton空函数名 Animation Event 仅出现于修复前的日志段;当前控制器已无空事件,重新导入后的后续运行记录未再出现该警告。未发现本轮商城运行时代码的异常。
2026-09-10:负责人要求商城主返回按证据诊断,不再猜测。场景树已确认
Product page只含展示卡牌 Scroll View,之前按“后退Button”绑定的对象均属其它页面;商城实际返回节点为ShopPage商店/Bottom page function bar/BackoffButton。现已精确绑定该节点,并新增开发期ClientShopNavigationDiagnostics,记录绑定、PointerDown/Up/Click、Button onClick 及处理前后商城/主页/导航器状态,供 Console 回传定位。另已清除Event MallButton.controller的Pressed动画中空函数名 Animation Event,消除该警告。待 Unity 自动编译与人工复现日志。
2026-09-10:负责人反馈商城主界面“后退Button”仍无效。已为
Product page下该按钮及其全部既有可射线子节点添加独立IPointerClickHandler,不再只依赖可能被通用返回组件重置的Button.onClick;点击时重置购买态、关闭商城弹层、调用统一导航ReturnHome,并以直接隐藏商城/激活主页作为导航状态异常时的兜底。待 Unity 自动编译与人工点击验证。
2026-09-10:商城逻辑正在替换为角色卡牌占位商品方案:已移除早期
ClientShopProduct、GetShopProducts与TryPurchaseShopProduct,改用可替换的ClientShopListing、批量购买与已购数量查询接口;本地单价暂定 10 水晶石。ClientShopPage正在绑定负责人已完成的商城 GUI(常规/活动页、购买弹窗、成功页、兑换码、订单和待发货)。Unity 命令行编译因已有 Unity Editor 占用工程而在脚本编译前退出,日志:Logs/codex-shop-compile.log;尚待 Editor 空闲后重验。
2026-09-10:根据负责人提供的 Unity Console,已删除
ClientShellDirectUpdater中仍调用旧商城 API 的三个早期编辑器路径(旧商城生成、商品确认生成、核心交互中的商城绑定)。此前ConfigureDetail、Purchase、Configure的 4 个CS1061阻断错误不再有源码引用;未触碰已完成的商城 GUI。待 Unity 自动重编译后确认 Console 无新错误。
2026-09-10:负责人提供的重编译 Console 只剩 4 个 Editor 警告,均已按来源修正:
AddBuildMapUtility避免遮蔽基类成员、AssetBundleTool移除已废弃的确定性选项、HybridCLR 自有命令移除不可达旧分支、CodeGuard 修正错误标记为校验器的实际菜单项(第三方目录改动由负责人本次“修警告”请求明确授权)。尚待 Unity 再次完成自动重编译确认无警告。
2026-09-10:负责人反馈主页商城图标无响应。已定位为主页只绑定旧名
ShopButton、而实际节点名为BottomFunctionIcon_Shop,且ClientUiNavigator被禁用导致导航事件无人处理;已补充图标绑定并启用导航器。PC 客户端会话新增allowPcServerConnection总开关,ClientShell配置为0:自动启动和手动启动都会只输出“客户端开发模式:已屏蔽”,不执行网关、TCP、握手或登录。未删除服务器代码;待 Unity 自动编译及点击验证。
2026-09-10:负责人提供的 Console 剩余 6 条警告已处理:
Init.OnCompleted去除无 await 的async;ClientTcpConnectionProbe的仅 WebGL 会话配置改在UNITY_WEBGL && !UNITY_EDITOR条件块内声明,避免 PC 编译把其序列化值判为未使用。未改变 WebGL 运行路径或 PC 连接屏蔽开关;待 Unity 自动重编译确认。
2026-09-10:商城层级与交互修正:所有商城页/弹层每次打开都会
SetAsLastSibling,购买成功页的全部现有可射线节点均绑定点击关闭,商城所有同名“后退Button”统一路由至Back,且返回导航改为全场景查找已启用的ClientUiNavigator。ClientUiFeedback的 Toast 会置顶并在 2 秒后自动隐藏;待 Unity 编译及手动点击验证。
2026-09-10:负责人反馈常规商城的展示卡牌 Scroll View 覆盖新弹层。已将商城页面/弹层打开时的提升策略扩展为根
Canvas.overrideSorting = true与递增sortingOrder,不再只调整 Transform sibling;因此购买、成功、兑换、订单和待发货会始终高于角色卡牌独立 Canvas。待 Unity 编译与手动验证。
2026-09-10:负责人反馈卡牌无法打开购买页、商城主后退未回主页、兑换码图标/文字无法聚焦。
OpenListing现实时刷新本地商城条目而非依赖进入页时缓存;ClientUiNavigator新增清空历史的ReturnHome并由商城主后退调用;兑换输入框的现有Image与Text (TMP)增加点击聚焦转发。待 Unity 编译和手动验证。
2026-09-09:已在 PC 与小程序共享的
ClientServerPacketRouter中将CLGTDisconnectNtf(模块 1、协议 2)分类为ClientGtDisconnectNotification,可读协议日志会输出断开码和中文原因(正常通知、超时、踢线、异地登录、维护、与平台/游戏服断连、系统错误、离线挂机等)。PCClientServerPcSession收到该包会输出原因;小程序ClientTcpConnectionProbe收到该包也会输出原因,且在英雄数据未完成时将其作为失败原因。未改变连接策略或添加自动重连。文本差异检查通过;Unity 命令行编译被当前打开的 Unity Editor 占用,未进入脚本编译,日志为Logs/codex-disconnect-notification-compile.log。
2026-09-09:PC 协议会话
session-20260909-194125.protocol.log已验证握手、游客登录(头像/头像框/称号/徽章/铭牌 ID 均已分类输出)及CLPFGetHeroAck全部成功,随后接收CLGTDisconnectNtf(模块 1、协议 2、9 字节)并发生远端强制断开。Editor.log 中“TCP 读取失败”由后台读取线程先收到连接重置、主线程后归档该断开通知的时序造成;本次没有协议解析失败或前置数据丢失证据。原始包文件仍被运行中会话占用,未读取断开通知的具体 code;若需要区分正常断开与踢线/维护,待会话关闭释放文件后再读取或在记录器中增加该协议摘要。
2026-09-09:
codex-clientgt-profile-sync-compile.log已显示 Unity 批处理完成,但其无窗口进程未自行退出并留下Temp/UnityLockfile,导致 Hub 显示项目仍打开。已确认无桌面 Editor 窗口后,仅结束本次由代理启动的 batchmode 进程并删除其 0 字节临时锁文件;项目锁已释放,未删除项目资源或用户数据。
2026-09-09:已按
D:\Users\Administrator\Desktop\弹珠配置\tools\jbproto\Protocol\ClientGT.lua/.hpp同步新版CLGTLoginAck:字段顺序为头像、头像框、称号、徽章、铭牌,后两项替代旧dan/decorate。项目ClientGT.cs的二进制读写已更新;PC 端GamePlayer保存五项装扮 ID;小程序ClientTcpConnectionProbe按同一顺序读取;ClientServerPacketRouter的登录摘要会分类输出五项内容 ID,继续隐藏用户 ID、昵称、手机号、令牌和点券。未主动发送登录/装扮业务请求。ClientPF.cs的协议 3–22 个性化分类保持生效。文本差异检查通过;Unity2022.3.57f1c2命令行编译已完成,日志Logs/codex-clientgt-profile-sync-compile.log包含Batchmode quit successfully invoked,未检出error CS。
2026-09-09:后端同步的
ClientPF.cs已包含个性化协议:称号、铭牌、徽章、头像、头像框的查询列表及装备/卸下(模块 2、协议 3–22)。ClientServerPacketRouter已补充分类和脱敏字段摘要:列表记录状态、数量和最多 20 个内容 ID,操作记录对象 ID、装备/卸下动作及回包状态;不会主动发送业务请求。初始检查时工作区未找到新版ClientGT.cs,后续已由负责人提供的.lua/.hpp核对并同步,详见本文件最新记录。Unity2022.3.57f1c2命令行编译已完成,日志Logs/codex-personalization-protocol-compile.log包含Batchmode quit successfully invoked,未检出error CS。
2026-09-09:负责人确认购买数量节点
Purchase quantity为TextMeshProUGUI。ClientShopPurchaseQuantityProgress的数量及端点文字引用已改用TMP_Text,可直接绑定该文字节点;长期基线已补充 TMP/UGUI 文本引用类型一致性与交互组件挂载位置约束。未改场景或 GUI。Unity 命令行编译再次被已打开的同项目 Unity 实例阻止,未进入脚本编译;日志为Logs/codex-shop-purchase-tmp-compile.log。
2026-09-09:新增
Assets/Client/Runtime/UI/ClientShopPurchaseQuantityProgress.cs,仅实现商城购买弹窗的数量选择进度条逻辑,未改场景、GUI、商品交易或本地服务。组件可按商品PurchaseLimit初始化 0 至最大值的离散挡位;支持减、加、最大值、拖动图标、图标数量/左右端点文字及填充进度同步。Unity 命令行编译被已打开的同项目 Unity 实例阻止,未进入脚本编译;日志为Logs/codex-shop-purchase-quantity-compile.log。待负责人关闭 Editor 后重跑编译并在ClientShell手动绑定现有节点验证。
2026-09-08:负责人反馈 7 页面仍出现叠加;已读取 Editor.log,当前日志只有旧
ClientProfileNavigationBinder的历史运行记录,没有新ClientProfileNavigationController的运行时记录,无法据此判断接管链路。已在新控制器加入临时诊断:启动绑定数量、顶部/底部 Toggle 路由、每次 Navigate/Back,以及 ApplyRoute 后实际激活页面数量。待负责人测试后根据[ClientProfileNavigationController]日志继续定位;本次未改 GUI。
2026-09-08:按负责人确认,删除旧的
ClientProfileNavigationBinder,改为ClientProfileNavigationController统一管理个人中心、主页展示及个性化 5 个页面,共 7 个互斥路由;顶部 3 个 Toggle 全局切换,个性化底部 5 个 Toggle 从现有持久化目标解析路由,后退使用历史栈。场景只保留一个活动路由,未调整 GUI。Unity 命令行编译仍被其他 Unity 实例占用,日志为Logs/codex-profile-route-controller-compile.log。
2026-09-08:已根据
C:\Users\Administrator\AppData\Local\Unity\Editor\Editor.log的真实运行日志修复主页展示后退:ReturnFromShowcase已收到点击,但个人中心 Toggle 原本就是True,因此没有触发 Toggle 事件;现在设置 Toggle 后始终显式调用ShowPage(_profilePage)。临时诊断已移除。Unity 命令行验证仍被其他 Unity 实例占用,日志为Logs/codex-showcase-back-fix-compile.log。
2026-09-08:已根据 Unity Editor.log 定位主页展示后退问题:按钮持久化回调正常触发,但“个人中心Toggle”原本已为
isOn=True,重复赋值不会触发onValueChanged,所以页面仍保持主页展示。ReturnFromShowcase现无论 Toggle 状态如何都会显式执行ShowPage(_profilePage);临时诊断组件已移除。
2026-09-08:修正主页展示后退与客户端初始页:
HomepageDisplayPage主页展示下现有后退Button已在场景中持久化绑定到PagesLayer导航绑定器,点击后选中“个人中心Toggle”;场景初始状态改为仅激活MainPage主页,ProfilePage个人中心初始关闭,需点击主页ProfileButton后才打开。未调整任何 GUI 尺寸、位置、层级或素材。
2026-09-08:按负责人要求不调整主页展示页面任何 GUI 尺寸、位置、层级或素材;仅在
ClientProfileNavigationBinder中绑定现有后退Button,点击后选中“个人中心Toggle”并返回个人中心。待 Unity Editor 空闲后进行命令行编译验证。
2026-09-08:已将个人中心导航绑定器挂到
ClientShell/PagesLayer。运行时按现有节点名绑定顶部“个人中心 / 主页展示 / 个性化”3 页;个性化进入时默认显示铭牌,并在 5 个个性化页面切换时刷新各自底部 5 项 ToggleGroup 的现有页面显隐事件。新增Assets/Client/Runtime/UI/ClientProfileNavigationBinder.cs;Unity 命令行日志为Logs/codex-profile-navigation-bind-compile.log,本次未取得实际编译结果,日志同时记录 Unity Licensing Client 访问令牌不可用与项目已被其他 Unity 实例占用。
2026-09-08:继续修复
ClientShell中个人中心相关两组“个人中心 / 主页展示 / 个性化” Toggle 的 Checkmark 常态显隐。两组共 6 个 Toggle 已解除graphic自动绑定,保留isOn、ToggleGroup 与页签切换事件;待 Unity Editor 关闭后完成命令行编译验证。
2026-09-07:修复
ClientShell中BadgePage/Panel的 5 个 Toggle Checkmark 显隐问题。已解除 Togglegraphic自动绑定,保留各 Toggle 的isOn与onValueChanged;场景中的 Checkmark 节点可常显。Unity 命令行编译因当前 Editor 占用项目未进入编译,证据见Logs/codex-badge-checkmark-compile.log。
当前短入口(2026-09-04):WebGL/微信 TCP 最小会话探针目标为“HTTP 获取 IP/端口 → TCP 建连 → 握手 → 游客登录 → 完整解析英雄数据 → 仅成功后主动关闭”。固定 device 为
WebGLMiniGameDeviceIdentifierPinballNode(40 位纯英文)。最新微信日志已确认 HTTP、TCP 与握手回包均成功;未进入游客登录的根因是探针附着的 BootInit对象在切换LoginScene时被卸载。探针现会迁移至独立的跨场景对象,待关闭当前 Unity Editor 后重新编译/同步 HotFix、构建并验证。
- 更新时间:2026-08-28
- 当前分支:
main - 当前阶段:C2「英雄、图鉴与背包」
- 当前唯一目标:在不影响原街机/战斗、服务端或总架构的前提下,建立可持续开发的微信小程序客户端界面与养成模块基础。
- 开发范围:养成、英雄/图鉴、背包、商城、邮箱、排行榜、活动、任务、扭蛋、个人中心及本地模拟逻辑。
- 交互范围权威输入:
D:\Users\Administrator\Desktop\J 界面交互草图-弹珠项目-小程序端.pdf。该 PDF 为单页全流程草图;其中已画出的页面、页签、跳转、空态、禁用态、弹窗、筛选与领取反馈属于客户端验收范围。 - 不开发:战斗/关卡、服务端、支付、账号、总架构;不改造既有
Boot、MainScene、LoginScene和街机战斗业务。 - 新功能入口:
Assets/Client/Scenes/ClientShell.unity,不加入现有 Build Settings;后续从该场景验证客户端页面。 - 保留现有 YooAsset、HybridCLR、XLua、URP 和微信 SDK;真实平台接入仅做接口准备。
- 已提交前的场景、热更新、YooAsset、HybridCLR、项目设置和微信 SDK 差异均视为既有受保护改动,禁止清理、重置、批量暂存或覆盖。
- 可再生产物(
Library/、Logs/、Temp/、.vs/、obj/、*.csproj、*.sln)仅记录为清理候选;本轮未删除。 - 历史 WebGL/小游戏调试证据保留于
BUG_TRACKER.md、VERSION_HISTORY.md和AI_MODEL_UPGRADE.md,不再作为 C0 的阻塞项。
-
2026-09-02 微信开发者工具自动预览失败,错误为
80051 source size 31013KB exceed max limit 30MB。已检查D:\Users\Administrator\Desktop\弹珠接入text_1\720\minigame,目录约 30.26 MiB,主要文件为data-package/*.webgl.data.unityweb.bin.br约 17.6 MB、wasmcode/*.wasm.br约 12.0 MB。结论为上传包超限,运行尚未开始,当前日志不能用于判断UnityWebRequest或 TCP;需先减少小游戏上传包约 1–2 MB,再继续验证。 -
2026-09-02 诊断微信日志“请求网关地址后无后续回调”:源码
NetController.cs已包含GetIpPortWithUnityWebRequest,但实际小游戏资源Assets/HotUpdateResources/Dll/WebGL/HotFix.dll.bytes与HybridCLRData/HotUpdateDlls/WebGL/HotFix.dll时间均为 2026-08-28 13:55:15,未包含本次 2026-09-02 的 UnityWebRequest 改动。结论为 HotFix DLL 未重新编译/同步,当前不是 TCP 或GetHeroReq问题。待关闭 Unity Editor 后执行Build/WebGL/Compile And Sync HotFix DLL,再重新生成 WebGL/小游戏资源并清理微信开发者工具旧缓存验证。 -
2026-09-02 已将
Assets/Main/Boot.unity中ClientTcpConnectionProbe.useDirectLocalTest改为0,保留runOnStart=1、useRealGuestLogin=1,下次小游戏启动将从本地直连切换为GetIpPort → UnityWebRequest网关发现流程。当前DefaultQLClient.ServerUrl仍为局域网 HTTP 地址,开发者工具验证需临时允许未校验合法域名;正式验证前仍需替换为服务端 HTTPS 网关域名。 -
2026-09-02 已按负责人提供的微信小游戏兼容方案改造
NetController.GetIpPort():WebGL/小游戏分支改为UnityWebRequest.Post协程,复用DefaultQLClient.ServerUrl、ClientGetGateConnectionRequest的zone_id、原 QL 参数、MD5 签名及 JSON/XML 解析,成功后继续写入SysDefines.Ip/Port并调用原连接回调;PC/Editor 分支仍保留旧 QL 客户端链路。当前网关地址未在仓库新增,小游戏正式验证前需将DefaultQLClient.ServerUrl配置为负责人提供的 HTTPS 网关域名,并在微信开发者工具加入 request 合法域名。Unity 批处理日志为Logs/codex-gateway-uwr-compile.log,已完成脚本编译并显示Batchmode quit successfully invoked,无本轮error CS;进程退出状态仍待系统回收确认,尚未进行小游戏人工验证。 -
2026-09-01 已重写
Assets/Client/Runtime/ClientTcpConnectionProbe.cs为小程序 TCP 客户端最小会话:连接后按旧协议握手(正确读取errcode + payload + random_key)、游客登录、登录成功后发送CLPFGetHeroReq(模块 2、协议 1、空请求体),并解析CLPFGetHeroAck(模块 2、协议 2)。解析英雄数据已包含新版CLPFHeroInfo.fightInt64字段及英雄组数据;默认不发送真实业务协议,需临时开启useRealGuestLogin。本轮命令行编译因 Unity 2022.3.57f1c2 工程被当前 Editor 占用而未进入编译,日志为Logs/codex-tcp-client-compile.log;待负责人关闭 Editor 后重试,并在微信开发者工具验证游客登录与 GetHero 响应。 -
2026-08-31 已新增加载页运行时逻辑:
IClientResourceLoadSource声明可替换的资源进度事件边界,ClientLoadingPage将进度映射到从左到右的Image.FillAmount并显示百分比,ClientLoadingDotsAnimator以不受 Time.timeScale 影响的协程让 1/2/3 三个加载点依次上移下落并循环。当前脚本已改为自动绑定负责人已有的“加载Page”节点,待挂载验证。 -
2026-08-31 已新增
ClientTcpConnectionProbe:通过既有NetController.GetIpPort获取网关地址,再调用微信 SDKWXBase.CreateTCPSocket仅验证 TCP 建连,成功后立即关闭,不发送登录或业务协议。因Assets/Client属于Assembly-CSharp,探针已改为反射调用 HotFix 类型,解除 AOT→HotFix 的链接依赖。微信运行日志已证明 Unity 与探针均正常启动;首次探针早于 HotFix 加载而退出,现已改为最多等待 15 秒,待NetController就绪后再请求网关。该 C# 改动待负责人关闭当前 Unity Editor 后执行 Unity 批处理编译,并重新构建/转换小游戏验证。 -
2026-08-31 TCP 探针复测证据:已输出“等待 HotFix 与 NetController 初始化”,但远程版本请求
https://<CDN域名>/1/HotUpdate/NewAB/WebGL/2026-08-28-720/StreamingAssets/yoo/DefaultPackage/PackageManifest_DefaultPackage.version返回 HTTP 404;本次日志没有网关 IP/端口、TCPSocket.connect、成功或失败回调。结论:当前尚不能判断服务器或 TCP,先修复/绕过该 YooAsset 远程版本文件路径后再验证。 -
2026-08-31 OSS 路径修复后复测:版本文件、Manifest 与 HotFix DLL 均已下载,
StartGame.Start、GameController.Init完成并进入大厅资源加载。探针仍只输出“等待 HotFix 与 NetController 初始化”;经代码检查,NetController.Instance为单例基类继承的静态属性,原反射查询缺少BindingFlags.FlattenHierarchy,已补齐。命令行 Unity 编译再次因负责人 Unity Editor 占用工程被拒绝,日志为Logs/codex-tcp-probe-compile.log;待关闭 Editor 后重新构建/转换小游戏验证。 -
2026-08-31 后续导出目录
D:\Users\Administrator\Desktop\弹珠接入text_1\720\minigame已在 18:22 重新生成,晚于探针修正时间;Boot.unity中ClientTcpConnectionProbe.runOnStart: 1。负责人提供的下一份开发者工具日志从运行 18 秒后的插件帧率监控开始,不含任何 Unity 启动段或[TCP探针]字样,不能作为 TCP 成功/失败证据;需清空 Console 后重新编译并从启动时采集。 -
2026-08-31 负责人确认运行中曾出现“
[TCP探针] HotFix 已就绪,开始请求网关 IP/端口(HTTP)”。结合NetController.asyncExecuteWebRequest的Task.Run(() => WebClient.Execute(...))和QLWebClient的System.Net.HttpWebRequest实现,当前 TCP 验证的阻塞点已确定为旧 HTTP 网关发现层:Unity WebGL 不支持System.Net网络类和线程,故不会进入网关回调及WXTCPSocket.connect。后续需负责人提供当前网关 HTTP 契约以实现UnityWebRequest适配,或提供非仓库化的固定测试主机/端口以跳过网关验证。探针日志已改为不记录真实 IP/端口。 -
2026-09-01 负责人提供局域网 TCP 测试目标;已为
ClientTcpConnectionProbe新增不含真实地址的useDirectLocalTest、directTestHost、directTestPort本地直连配置。启用后会跳过旧 HTTP 网关,直接调用微信TCPSocket.connect,成功后立即关闭且不发送业务数据。真实地址仅由负责人临时在 Inspector 输入,禁止保存、提交或写入日志。Unity 批处理Logs/codex-tcp-probe-direct-compile.log已出现Tundra build success,但进程仍处于资源刷新,尚未有最终Exiting batchmode successfully退出标记。 -
2026-09-01 局域网最小 TCP 连通性验证通过:微信开发者工具日志依次出现“使用本地直连测试参数”“已调用微信
TCPSocket.connect”“TCP 建连成功;未发送任何业务数据”“TCP 连接已关闭”。结论仅覆盖开发者工具到当前局域网测试目标的 TCP 建连;不覆盖 HTTP 网关发现、登录/业务协议、真机网络、正式域名白名单或线上服务器。测试完成后必须清空本地直连参数并禁止提交。 -
2026-09-01 已只读审查旧 TCP 协议:每个包为“小端 4 字节总长度(含长度字段)+ 2 字节模块 ID + 2 字节协议 ID + 正文”;旧心跳请求为模块 1、协议 8,应答为模块 1、协议 9 且携带状态码。但旧连接流程要求先执行握手,握手包含平台、版本及设备标识,不能在未取得服务端确认的情况下假定它无副作用。微信 SDK 已具备二进制
TCPSocket.write和onMessage能力;当前探针仍刻意未注册收包或发送。下一步需服务端负责人书面确认“握手+一次心跳”可用于测试,或提供独立 echo 测试契约(请求字节、期望响应、无副作用保证),然后才可扩展探针进行实际收发验证。 -
2026-09-01 负责人已明确授权当前服务器的真实登录验证。
ClientTcpConnectionProbe已扩展为仅在“本地直连 +useRealGuestLogin”均开启时执行一次“旧协议握手 → 取得随机密钥 → 旧协议游客登录 → 接收登录响应 → 关闭”的最小链路。地址、token、随机密钥及用户资料均不记录;日志只输出包长度、协议阶段和响应状态。Unity2022.3.57f1c2批处理命令已执行,但被当前同版本 Editor 的项目锁阻止,未进入编译;日志为Logs/codex-tcp-real-login-compile.log。未关闭负责人 Editor,待其在当前 Editor Console 确认无编译错误后进行 WebGL/微信小游戏人工验证。 -
2026-09-01 微信开发者工具存在高频“request 错误”日志,普通 Console 记录会被刷出缓冲区。探针已增加仅在真实登录测试开启时显示的微信原生结果弹窗,覆盖连接失败、异常数据、无效包、握手拒绝、登录成功/拒绝与登录超时;弹窗不显示地址、token、随机密钥或用户资料。第二次 Unity
2022.3.57f1c2批处理仍因打开的 Editor 项目锁而未编译,日志为Logs/codex-tcp-login-modal-compile.log。待当前 Editor 自动编译确认后重新导出小游戏验证。 -
2026-09-01 已用两个负责人提供的候选端口进行真实登录测试;两次均出现“TCP 建连成功 → 已发送 62 字节旧协议握手 →
ECONNRESET”,无握手响应。结论:小游戏的 TCP 建连与二进制发包均已验证;候选端口的服务端在解析/拒绝握手后主动断开,尚未验证登录或收包。探针弹窗已修正为在该状态显示“建连成功后被服务器断开”;当前批处理仍被已打开的 Editor 锁阻断,日志为Logs/codex-tcp-reset-message-compile.log。不再盲测端口,等待服务端确认网关端口及握手兼容性。 -
2026-09-03 已重新核对 PC 端
ClientGT.cs、新ClientPF.cs、ClientPFResponser.cs、NetController.cs与微信ClientTcpConnectionProbe.cs:微信当前发送CLPFGetHeroReq(模块 2、协议 1),按新CLPFGetHeroAck顺序读取英雄数组与英雄队伍数组,现有日志已显示获取英雄成功。探针新增可选logDeviceIdentifier,开启后仅打印设备来源、长度、首尾片段和 SHA-256 指纹,不打印完整设备值。Unity 批处理再次被已打开 Editor 锁阻止,日志为Logs/codex-tcp-device-log-compile.log;需在当前 Editor 自动编译后导出验证。 -
2026-09-03 负责人明确授权内网临时查看完整机器码。探针新增默认关闭的
logFullDeviceIdentifier,仅在同时开启设备诊断时打印完整值;测试结束必须关闭并清理临时构建/日志,不得提交或用于正式包。批处理验证日志为Logs/codex-tcp-full-device-compile.log,当前仍受已打开 Editor 项目锁影响。 -
2026-09-03 最新微信运行日志显示启动阶段通过 CDN 请求
e112a2cd0d6ade4f.webgl.data.unityweb.bin.br并返回 404,随后start game fail: 404;本地新导出文件存在于D:\Users\Administrator\Desktop\弹珠接入text_1\720\webgl。此前“仅脚本改动无需上传 OSS”的判断不适用于当前 CDN 配置:WebGL 重新导出产生了新的带 hash 数据文件,必须上传该文件(及实际出现 404 的其他 CDN 文件)或清空 CDN 配置改用本地包。 -
2026-09-03 新日志已无 WebGL 资源 404,且出现 TCP 建连、握手、游客登录、
CLPFGetHeroReq发送及英雄回包解析日志,说明小游戏到服务器的游客 TCP 登录和 GetHero 数据链路已跑通。设备诊断显示SystemInfo.deviceUniqueIdentifier返回n/a(长度 3);探针已修正为将n/a、unknown、undefined、全零及过短值视为占位值并回退PlayerPrefs.DeviceId。批处理日志为Logs/codex-tcp-device-fallback-compile.log,仍因打开 Editor 项目锁未进入编译;待 Editor 自动编译后重新导出验证回退值。 -
负责人新增长期决定:已有 UI 页面默认只写脚本,不新建 Page、UI 节点,不替换素材或改变 GUI 排版;场景结构修改必须得到明确授权。
-
已建立客户端目录/模块说明和独立场景;
ClientBootstrap默认注册本地模拟账户、货币、英雄与背包服务,未触碰既有街机启动链或网络层。 -
ClientShell已切换为“场景可编辑 UI”路径:运行时页面脚本仅负责数据绑定和导航;Assets/Client/Editor/ClientShellUiBuilder.cs会在编辑器中生成ClientCanvas、MainPage、ProfilePage、按钮与改名弹窗,避免运行时临时创建 UI。 -
首次执行 UI 生成工具时,Unity 2022.3.57f1c2 报出内置字体
Arial.ttf已失效;现已改用其要求的LegacyRuntime.ttf。该次生成在第一个文字节点前中断,需删除已生成的ClientCanvas后重新执行菜单。 -
场景首次运行曾因
MainPage.OnEnable早于ClientBootstrap.Awake访问本地服务而报错;页面首轮绑定已改为Start,重新启用页面时才在OnEnable刷新,消除了根节点启用顺序依赖。 -
主页与个人中心使用负责人提供的参考图作为临时构图底图,展示本地名称、ID、战力;主页可进入个人中心,个人中心支持返回与本地改名。未完成入口只显示待开发提示,不进入旧街机页面。
-
主页展示页已实现本地最小闭环:根据本地英雄拥有状态选择展示立绘、确认后写回
IClientDataService。展示资源位于UI/HomeDisplay;第二名示例英雄未拥有,选择时应提示锁定。 -
主页面所有一级入口已由“待开发提示”改为实际导航。英雄和背包页展示本地模拟列表;其余入口先进入统一内容页并保留返回主页,待对应规则/交互稿细节实施后替换为独立页面。
-
负责人已确认主页面必须由独立可编辑的 Scene 节点构成。生成器已改为不使用
HomeReference.png,改为创建背景、主立绘、头像框、头像、顶部栏、战力栏、编队/弹珠卡、底部导航及独立入口节点;已有旧 Canvas 需由负责人删除后重建。 -
已定位主页素材未显示的直接证据:复制进工程的 PNG 默认
textureType: 0、spriteMode: 0,LoadAssetAtPath<Sprite>会得到空对象。生成器现会在首次构建前将UI/MainPage/Sprites中的纹理统一设置为单图 Sprite 后再生成节点。 -
已进入 C2 英雄/图鉴页面:拆分素材已复制至
Assets/Client/UI/HeroPage/Sprites,不使用整张参考图;英雄/图鉴页签、全/火/水/风筛选、已拥有/未拥有示例英雄卡和返回主页已可演示。 -
英雄详情页已使用
Assets/Client/UI/HeroDetailPage/Sprites的拆分素材直接写入ClientShell:HeroDetailPage、背景、战力区、属性区、技能区、文案和返回按钮均为可单独选中的场景节点。点击已拥有英雄会由ClientPageNavigator打开详情页,并绑定本地名称、等级、战力;返回会回到英雄页。技能、装备和真实数值仍待确认。 -
英雄页卡牌视觉已补齐为独立节点:品质框、属性图标、三颗星级和未拥有遮罩/文案均可在 Hierarchy 调整。现有全/火/水/风筛选、已拥有英雄详情入口和未拥有提示保持不变;尚未提供独立英雄立绘,因此继续复用已有的英雄卡素材。
-
背包页已直接写入
ClientShell:BackpackPage、筛选按钮、材料槽、装备槽、状态文案和返回按钮均为可编辑场景节点。主页底部背包入口进入该页;数据来自IClientDataService.GetInventory(),支持全部/材料/装备筛选及条目选中提示。背包专用切图、道具名称/图标和出售/合成/装备规则待确认。 -
负责人已将优先级调整为“先完成主页所有可点击一级界面”。扭蛋、商城、邮箱、排行榜、活动、任务、公告已从统一
FeaturePage拆成独立的GachaPage、ShopPage、MailPage、RankPage、ActivityPage、TaskPage、NoticePage场景根节点;每页有独立标题、状态区和返回主页按钮,并由共享导航控制器分发。当前仅完成本地展示/返回闭环,业务数据和规则待对应资料确认。 -
客户端 UI 已按统一 Canvas 架构重构:
ClientCanvas是唯一 UI 宿主,包含PagesLayer、PopupLayer、SystemLayer。现有所有客户端页面根节点已迁入PagesLayer;ClientUiPageId、ClientUiPage和ClientUiNavigator负责页面标识、生命周期(Enter/Pause/Resume/Exit)与返回栈。旧ClientPageNavigator已在ClientShell停用,不再参与运行时导航;所有现有返回按钮由ClientUiBackButton在运行时接入统一返回栈。 -
个人中心、主页展示、铭牌、英雄详情已接入新页面栈:个人中心的“主页展示”与“个性化”分别进入展示页和
BadgePage;铭牌页使用UI/BadgePage/Sprites中的拆分素材,提供三项选择、预览和本地确认;英雄详情新增元素、星级、拥有状态绑定。真实解锁、装备/技能、铭牌服务器同步仍待确认。 -
2026-08-28 已针对运行中反馈补强统一导航:主页每次显示都会重新接管所有一级入口(含头像/资料),返回按钮每次启用都会重接
ClientUiNavigator.Back;返回栈因域重载或 Inspector 直接激活而为空时会兜底回到主页。待 Unity Editor 自动重编译后的人工验证与关闭 Editor 后的命令行编译。 -
2026-08-29 已完成扭蛋与商城页的本地模拟闭环:
ClientGachaPool/TryDrawGacha演示单抽、十连、钻石不足、奖励结果和英雄解锁;ClientShopProduct/TryPurchaseShopProduct演示商品、余额校验、限购与奖励入背包。ApplyGachaPage、ApplyShopPage已将二者写入ClientShell的PagesLayer,页面根及其背景、标题、货币、商品/抽取按钮、结果/状态和返回按钮均为可编辑场景节点。正式概率、保底、运营周期、商品价格、限购与货币规则仍待产品确认。 -
2026-08-29 已完成邮箱页本地模拟闭环:
ClientMail、读取和附件领取均通过IClientDataService处理;MailPage可展示未读/已领状态、阅读详情、领取附件、重复领取提示和空列表节点。ApplyMailPage已将页面节点写入PagesLayer;真实邮件协议、有效期、批量领取和附件类型仍待产品确认。 -
2026-08-29 已完成排行榜页本地快照展示:榜单通过
ClientRankEntry/GetRankEntries提供,页面显示前三名、自己的排名与刷新状态;真实赛季、奖励、跨服与实时刷新待服务端契约。首次ApplyRankPage在Logs/codex-rank-page-apply.log因未先添加ClientRankPage组件出现空引用,已按定位补齐组件创建;重试成功并写入PagesLayer。 -
负责人已确认后续无素材页面的视觉实施规则:先按交互草图生成可编辑的完整页面版式骨架,再由负责人替换节点素材;不再使用通用纯色占位页作为页面成品。草图已完成视觉核对,活动、任务与公告等后续页面将沿用其“顶部标题/页签、主体内容卡或列表、状态信息、固定底部操作/返回”的结构。
-
2026-08-29 已完成活动页本地模拟闭环并按草图结构落地:
ClientActivity/TryClaimActivity支持活动状态、进度、领取成功、进度不足与重复领取;ActivityPage含标题栏、页签、活动卡、详情面板、领取区和返回入口,均为PagesLayer下可替换的场景节点。运营日历、真实活动条件、奖励配置和红点规则待产品/服务端确认。 -
2026-08-29 已完成任务页本地模拟闭环并按草图结构落地:
ClientTask/TryClaimTask支持任务进度、领取成功、未完成与重复领取;TaskPage含标题栏、每日/成长页签、任务卡、详情面板、领取区和返回入口,均为PagesLayer下可替换的场景节点。日/周重置、真实任务条件、奖励配置和红点规则待产品/服务端确认。 -
2026-08-29 已完成公告页本地模拟闭环并按草图结构落地:
ClientNotice/TryReadNotice支持公告列表、未读状态、阅读详情和空态;NoticePage含标题栏、公告列表区、详情区和返回入口,均为PagesLayer下可替换的场景节点。真实运营后台、公告有效期、排序与推送规则待产品/服务端确认。 -
2026-08-29 已完成英雄培养最小闭环:英雄详情新增“培养”入口,
HeroEnhancePage可展示等级、战力、金币/材料消耗并执行TryUpgradeHero;成功时扣除本地资源、提升英雄及主页战力,覆盖材料不足、金币不足和本地等级上限。正式升级公式、材料类型、等级上限、升星与装备规则待产品确认。 -
2026-08-29 已补齐背包本地锁定交互:选择材料或装备后可切换锁定/解锁,状态经
TrySetInventoryItemLocked写回本地数据并显示在条目文本;LockToggleButton已写入现有BackpackPage。装备穿戴、出售/分解、批量操作和真实锁定协议待产品/服务端确认。 -
2026-08-29 已在英雄培养页补齐本地升星:
TryStarUpHero会消耗本地金币与材料、提升星级及英雄/主页战力,并覆盖资源不足与星级上限。StarUpButton已写入HeroEnhancePage;正式升星条件、消耗、成功率与星级效果待产品确认。 -
2026-08-29 已在背包补齐本地装备/卸下:选中演示装备后可装备给本地演示英雄或卸下,锁定装备会被阻止操作;装备状态经
EquippedHeroId写回并显示在条目中。装备槽位、属性、替换确认与战斗数值影响不在当前授权范围。 -
2026-08-29 已打通扭蛋与英雄图鉴的本地拥有状态:扭蛋获得第二名英雄后,英雄页会移除锁定遮罩、显示英雄名并允许进入详情;未获得时保持锁定提示。该同步使用同一
IClientDataService英雄数据,不新增临时状态。 -
TeamButton/GachaButton 作为独立预制体放入 MainPage 后,导航由
ClientHomePage按 Root 名称在运行时绑定,避免替换预制体导致生成器一次性 Button 回调丢失。 -
下一检查点:按统一页面架构逐页补齐一级页面已确认交互;新增弹窗统一放入
PopupLayer,全局提示/加载统一放入SystemLayer,不再新增独立导航器或运行时业务 UI 根。 -
2026-08-29 缺口盘点:主页的编队与弹珠入口目前复用英雄页,尚未形成独立的编队/弹珠页面;扭蛋缺卡池切换、结果弹窗和历史,商城缺商品详情/确认,邮箱缺批量领取/筛选,活动/任务/公告缺真实页签切换与筛选,英雄/背包缺装备详情/替换确认和养成预览,通用
PopupLayer/SystemLayer的弹窗、红点、加载尚未实现。后续按当前计划逐项补齐;服务端、支付、战斗、真实运营配置仍不在范围内。 -
2026-08-29 已完成缺口计划的第一批:主页“编队”与“弹珠”已不再复用英雄页,分别进入
FormationPage和MarblePage;前者支持选择已拥有英雄进入单出战槽位,后者支持选择已拥有弹珠装备,均使用IClientDataService本地保存状态。队伍人数、编队属性、弹珠战斗效果与真实资源解锁仍待产品/服务端契约。 -
2026-08-29 已补充扭蛋抽取历史:
GetGachaHistory记录本地抽取次数,GachaPage显示“暂无抽取记录/已抽取次数”;历史节点已写入页面,卡池切换与结果弹窗仍待完成。 -
2026-08-29 已实现扭蛋结果弹窗代码:
ClientGachaResultPopup归属PopupLayer,单抽/十连成功后展示奖励并可关闭;ApplyGachaResultPopupPass已准备将弹窗节点写入ClientShell,待 Unity 批处理完成场景写入确认。 -
2026-08-29 扭蛋结果弹窗已实际写入
ClientShell/ClientCanvas/PopupLayer/GachaResultPopup;正确版本 Unity 2022.3.57f1c2 批处理成功,日志为Logs/codex-gacha-result-popup-apply-57.log。 -
2026-08-29 已补充邮箱批量领取与筛选逻辑:
IClientDataService.ClaimAllMails、ClientMailPage.ShowAll/ShowUnread/ClaimAll覆盖全部/未读和一键领取;场景按钮由ApplyMailBatchAndFilterPass写入,待 Unity 批处理验证。 -
2026-08-29 已补充活动/任务“进行中/已领取”筛选逻辑及场景写入器
ApplyActivityTaskFilterPass,待 Unity 批处理验证。 -
2026-08-29 已完成商城商品详情与二次确认逻辑:首次点击商品只选中并展示价格/奖励,
ConfirmPurchase才执行扣款和入包;ApplyShopConfirmPass负责写入详情与确认按钮。 -
2026-08-29 已补充背包道具详情展示:选中材料/装备时显示数量、装备状态及待确认属性说明;
ApplyBackpackDetailPass负责写入详情节点。 -
2026-08-29 核心本地交互已完成场景落地:
ApplyCoreInteractionScenePass已将商城详情/确认、邮箱全部/未读/一键领取、活动与任务筛选、公告全部/未读、背包详情一次性写入ClientShell。活动和任务复用现有顶部页签节点并附加按钮回调,不创建覆盖节点。 -
2026-08-29 已完成
SystemLayer统一反馈:UiFeedback包含可编辑的 Toast 与 Loading 节点;商城购买失败/成功及邮箱一键领取接入 Toast。主页的邮件、活动、公告入口已增加RedDot,由本地数据的未读/可领取状态刷新。 -
2026-08-29 已补齐核心防误触和养成预览:装备首次点击穿戴只进入确认态,再次点击才执行;英雄培养页显示升级/升星后等级和星级预览。本地演示仅有一件装备,真实多装备替换规则仍待产品配置。
-
2026-08-29 已实现五个底部导航的选中视觉代码:个人中心/弹珠/主页/背包/活动未选中使用各自
2.png白色图标,选中使用1.png黄色图标,并显示独立*_SelectedFrame高亮底框;主页默认选中,跳转与返回主页均会刷新选中项。场景写入入口为ApplyBottomNavigationSelectionPass。
-
2026-08-31 已执行 Unity
2022.3.57f1c2批处理场景写入与编译,日志为Logs/codex-loading-page-apply.log;退出日志为Exiting batchmode successfully now!,包含Tundra build success和加载页写入成功信息,未检出本轮error CS或异常。仍需负责人打开场景进入 Play Mode,手动提供一个实现IClientResourceLoadSource的加载器并验证视觉节奏。 -
铭牌素材首次导入尝试未写入资源:PowerShell 对
Copy-Item -LiteralPath "...\\铭牌\\*"不解析通配符,报路径不存在;目标Assets/Client/UI/BadgePage/Sprites保持为空。已定位为复制命令参数问题,后续仅以明确目录枚举重试。 -
个人中心/铭牌/英雄详情场景写入首次批处理未执行:
Logs/codex-personal-pages-apply.log报“another Unity instance is running with this project open”。当前有一个由 Hub 启动的主 Unity Editor 及两个其子进程,均不得由自动化结束;素材已复制至Assets/Client/UI/BadgePage/Sprites,代码尚待该 Editor 关闭后执行ApplyPersonalCenterPages编译与场景写入。 -
负责人关闭 Editor 后,已执行
ClientShellDirectUpdater.ApplyPersonalCenterPages:退出码0,场景已保存,日志为Logs/codex-personal-pages-apply-retry.log;日志包含Tundra build success、个人中心/展示/铭牌/英雄详情写入成功和Exiting batchmode successfully now!,未检出本轮编译错误或异常。 -
2026-08-28 已以 Unity
2022.3.57f1c2批处理执行ClientShellDirectUpdater.ApplyHeroDetailPage:脚本编译图构建成功,退出码0,日志为Logs/codex-hero-detail-apply.log;日志包含Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。既有项目警告仍存在:Assets/Main/Init.cs的 CS1998、Assets/Editor/AddBuildMapUtility.cs的 CS0108、旧 AssetBundle API 的 CS0618 与 HybridCLR 编辑器代码的 CS0162。 -
2026-08-28 已以同一 Unity 批处理执行
ClientShellDirectUpdater.ApplyBackpackPage:退出码0,场景已保存,日志为Logs/codex-backpack-apply.log;日志包含Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
英雄卡视觉增补的首次批处理在
Logs/codex-hero-visual-pass.log中止:场景加载后GameObject.Find("HeroPage")无法找到被禁用的页面根。已定位为 Unity 的活动对象查找限制,改为包含禁用对象的组件查找后再继续;首次命令未写入场景。 -
修正后已执行
ClientShellDirectUpdater.ApplyHeroVisualPass:退出码0,场景已保存,日志为Logs/codex-hero-visual-pass-retry.log;日志包含Tundra build success与Exiting batchmode successfully now!,未检出本轮编译错误或异常。 -
2026-08-28 已执行
ClientShellDirectUpdater.ApplyPrimaryPages:退出码0,场景已保存,日志为Logs/codex-primary-pages-apply.log;日志包含Tundra build success与Exiting batchmode successfully now!,未检出本轮编译错误或异常。 -
2026-08-28 已执行
ClientShellDirectUpdater.ApplyCanvasUiArchitecture:退出码0,场景已保存,日志为Logs/codex-client-ui-architecture.log;日志包含Tundra build success与Exiting batchmode successfully now!,未检出本轮编译错误或异常。 -
2026-08-28 已在 Editor 释放后以 Unity
2022.3.57f1c2批处理编译导航修复:退出码0,日志为Logs/codex-navigation-fix-compile.log;日志含Tundra build success与Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。仍待负责人在 Play Mode 走通头像 → 个人中心 → 主页展示/个性化(铭牌)及返回。 -
2026-08-29 已以同一 Unity 批处理分别执行
ClientShellDirectUpdater.ApplyGachaPage与ApplyShopPage:退出码均为0,日志为Logs/codex-gacha-page-apply.log、Logs/codex-shop-page-apply.log;均含Tundra build success、页面写入成功与Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
2026-08-29 已以同一 Unity 批处理执行
ClientShellDirectUpdater.ApplyMailPage:退出码0,日志为Logs/codex-mail-page-apply.log;包含Tundra build success、邮箱页面写入成功与Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
2026-08-29 已以同一 Unity 批处理重试执行
ClientShellDirectUpdater.ApplyRankPage:退出码0,日志为Logs/codex-rank-page-apply-retry.log;包含Tundra build success、排行榜页面写入成功与Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
2026-08-29 已以同一 Unity 批处理执行
ClientShellDirectUpdater.ApplyActivityPage:退出码0,日志为Logs/codex-activity-page-apply.log;包含Tundra build success、活动页面写入成功与Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
2026-08-29 已以同一 Unity 批处理执行
ClientShellDirectUpdater.ApplyTaskPage:退出码0,日志为Logs/codex-task-page-apply.log;包含Tundra build success、任务页面写入成功与Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
2026-08-29 已以同一 Unity 批处理执行
ClientShellDirectUpdater.ApplyNoticePage:退出码0,日志为Logs/codex-notice-page-apply.log;包含Tundra build success、公告页面写入成功与Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
2026-08-29 已以同一 Unity 批处理执行
ClientShellDirectUpdater.ApplyHeroEnhancePage:退出码0,日志为Logs/codex-hero-enhance-page-apply.log;包含Tundra build success、英雄培养页面与详情入口写入成功及Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
2026-08-29 已以同一 Unity 批处理执行
ClientShellDirectUpdater.ApplyBackpackInteractionPass:退出码0,日志为Logs/codex-backpack-interaction-apply.log;包含Tundra build success、背包交互节点写入成功及Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
2026-08-29 已以同一 Unity 批处理编译英雄拥有状态联动:退出码
0,日志为Logs/codex-hero-ownership-sync-compile.log;包含Tundra build success与Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
2026-08-29 已以同一 Unity 批处理执行
ClientShellDirectUpdater.ApplyHeroEnhanceStarPass:退出码0,日志为Logs/codex-hero-enhance-star-apply.log;包含Tundra build success、英雄培养升星节点写入成功及Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
2026-08-29 已以同一 Unity 批处理再次执行
ClientShellDirectUpdater.ApplyBackpackInteractionPass写入装备切换按钮:退出码0,日志为Logs/codex-backpack-equip-apply.log;包含Tundra build success、场景写入成功及Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
2026-08-29 已以同一 Unity 批处理执行
ClientShellDirectUpdater.ApplyFormationAndMarblePages:退出码0,日志为Logs/codex-formation-marble-apply.log;包含Tundra build success、编队与弹珠页面写入成功及Exiting batchmode successfully now!,未检出本轮error CS、Exception或编译失败。 -
2026-08-29 扭蛋历史首次编译在
Logs/codex-gacha-history-apply.log因记录插入错误位置出现CS0103,已按日志定位修正;重试Logs/codex-gacha-history-apply-retry.log退出码0,场景写入与 Unity 编译通过。 -
2026-08-29 扭蛋结果弹窗批处理首次启动触发 Unity 资源导入,期间未到达执行方法日志;Unity 进程随后退出但日志无最终退出标记,需在缓存稳定后重新执行并核对
Tundra build success/Exiting batchmode successfully now!。本轮未结束任何负责人 Unity 进程。 -
2026-08-29 使用正确 Unity 2022.3.57f1c2 完成纯批处理编译,
Logs/codex-client-full-compile-57.log含Tundra build success与Exiting batchmode successfully now!,未检出error CS。邮箱/活动/任务/公告新增场景控件写入器因 Unity 启动竞争尚未得到独立落盘日志,逻辑代码已进入编译输入,需下一轮在 Unity 空闲时执行对应方法。 -
2026-08-29 核心交互第二轮纯编译
Logs/codex-core-interaction-compile-2.log通过;商城/背包场景写入尝试未生成独立日志,不能视为已落盘,需 Unity 空闲后执行ApplyShopConfirmPass、ApplyBackpackDetailPass、ApplyMailBatchAndFilterPass、ApplyActivityTaskFilterPass、ApplyNoticeFilterPass。 -
2026-08-29 已用 Unity 2022.3.57f1c2 成功执行核心交互场景写入,
Logs/codex-core-interaction-scene-apply.log含Tundra build success、节点写入成功及Exiting batchmode successfully now!;系统反馈与红点写入日志为Logs/codex-system-feedback-apply.log、Logs/codex-home-red-dot-apply.log,均通过。最终代码编译为Logs/codex-core-local-final-compile.log,未检出error CS或Exception。 -
2026-08-29 底部导航选中状态首次写入未执行:
Logs/codex-bottom-navigation-selection-apply.log明确显示another Unity instance is running with this project open,Unity 在加载工程前退出,未产生场景或编译改动。等待负责人关闭该工程的 Unity Editor 后,仅执行一次ApplyBottomNavigationSelectionPass并验证日志;不自动结束负责人的进程。 -
2026-08-29 负责人关闭 Unity Editor 后已成功执行
ApplyBottomNavigationSelectionPass:Logs/codex-bottom-navigation-selection-apply.log含Tundra build success、五个底部导航选中状态写入成功及Exiting batchmode successfully now!。ProfileButton、MarbleButton、HomeButton、BackpackButton、ActivityButton均有白色未选中图标、黄色选中图标和可编辑的*_SelectedFrame高亮底框。 -
2026-08-29 已将负责人提供的
D:\Users\Administrator\Desktop\UI\切图(11)原样复制为独立素材目录Assets/Client/UI/切图(11),共 358 个 PNG,未覆盖现有页面素材或场景引用。该目录等待 Unity 导入完成后按页面逐项替换;使用单张切图前需设置为Sprite (2D and UI)。 -
BUG-009至BUG-013和RISK-010、RISK-011仍是既有微信/WebGL 调试风险,后续只有接入旧启动/资源链时才按编号恢复。
- 首个优先页面(建议先做大厅/个人中心或英雄/背包)。
- UI 适配基线、字体/图标来源、最终美术资源和性能预算。
- 养成、装备、货币与奖励的真实数值/规则来源;确认前仅实现可配置的本地示例数据。
- 已检查微信小游戏导出目录
D:\\Users\\Administrator\\Desktop\\弹珠接入text_1\\720\\minigame:当前源文件总量约 31.73 MB,超过微信 30 MB 上传限制;主要体积来自 data-package 约 17.65 MB 与 wasmcode 约 12.01 MB,不能直接删除。 - 已反查
Assets/Effects ALL/unity tex/8K.png的 GUID701e45d0f28ccd34580e3f64324a7d17,在工程场景、Prefab、脚本、配置中未发现外部引用;已将该 PNG 及其.meta从工程移至D:\\Users\\Administrator\\Desktop\\pinball-resource-quarantine-20260902\\Effects ALL\\unity tex,保留可恢复副本,未直接永久删除。 - 其他大体积候选(战斗 UI 字体/图集等)仍有明确 Prefab 或 ClientShell 引用,未清理。旧导出包未改变,需重新导出后才能验证体积和运行效果。
- 2026-09-02 已将
Assets/WX-WASM-SDK-V2/Editor/MiniGameConfig.asset的ProjectConf.assetLoadType固定为0(CDN)。SDK 会将game.js的资源根替换为CDN/Assets,不再把首资源包放入小游戏包;重新导出前需确认 CDN 对应目录已上传并可公开 HTTPS 访问。 - 2026-09-02 重新导出验证:
minigame已降至约 15.75 MB,game.js已生成DATA_CDN且loadDataPackageFromSubpackage: false;data-package仅保留空占位文件。对当前 CDN 地址探测数据文件返回 404,说明资源尚未上传或路径不匹配,暂不能直接预览验证。 - 2026-09-02 微信日志进一步确认 CDN 已生效但数据文件返回 404;日志请求文件名为
97be491cfe81277d.webgl.data.unityweb.bin.br,与当前检查到的新导出文件名a81346d6b223f67d.webgl.data.unityweb.bin.br不一致,需重新导入最新导出目录或按最新game.js的DATA_FILE_MD5上传对应文件。 - 2026-09-02 已完成
2026-08-28-720的 YooAsset 增量构建;本地输出目录包含一套运行时清单PackageManifest_DefaultPackage_2026-08-28-720.bytes/.hash与PackageManifest_DefaultPackage.version。同目录的PackageManifest_*.json、BuildReport_*.json、buildlogtep.json是报告/日志,不作为运行时清单上传。 - 2026-09-02 OSS 根目录在线探测:
PackageManifest_DefaultPackage.version/.bytes/.hash返回 200,但最新数据文件97be491cfe81277d.webgl.data.unityweb.bin.br与 bundle(含65fe2931113959a247385aecb582299e.bundle)返回 404;说明只更新了清单,仍需上传数据文件和全部 bundle。 - 2026-09-02 再次探测:
PackageManifest_DefaultPackage.version/.bytes/.hash与最新数据文件97be491cfe81277d.webgl.data.unityweb.bin.br已返回 200;65fe2931113959a247385aecb582299e.bundle、a3c400ea8fa068e432ee745022f0711e.bundle、bf71706251bf4132766a28b15d0b446c.bundle仍返回 404,bundle 尚未全部位于 CDN 根目录。 - 2026-09-02 更正验证:上述三个 404 哈希属于旧日志,不在当前构建目录,不能作为当前上传判断。当前构建清单中 HotFix bundle 的 FileHash 为
f2f6a09db1e4930193e8b772ff1d8dd1;该 bundle、其他当前构建 bundle 示例、清单和97be491cfe81277d.webgl.data.unityweb.bin.br均已从 OSS 根目录返回 200。 - 2026-09-02 最新微信日志仍请求
c233ed8e38c5d8c785e8244969fba8c7.bundle并返回 404,随后因 HotFix.NetController 未加载在 15 秒超时。已核对该文件既不在当前2026-08-28-720本地输出(47 个 bundle),也不在 OSS;当前本地与 OSS 的 version、manifest bytes、manifest hash 三件套一致,因此优先怀疑微信开发者工具仍使用旧资源缓存或运行时加载了旧清单引用。处理顺序:清除开发者工具全部缓存并重新导入最新minigame;若仍请求c233...,需回查生成该旧引用的导出/清单来源,不应伪造或上传本地不存在的 bundle。 - 2026-09-02 15:43 新日志确认
c233...对应assets_hotupdateresources_dll_webgl_mscorlib_dll.bundle。当前构建报告/清单对应的 mscorlib 文件为26efc0d84c5d4b11e39fb99673983285.bundle,本地和 OSS 均可访问(200,1,165,915 bytes),而c233...本地不存在且 OSS 为 404。由此当前运行实例实际使用的是旧清单/缓存引用;无需修改 TCP 或 NetController 代码。若清除缓存并重新导入后仍请求c233...,应先关闭并重新打开微信开发者工具、删除该项目后从最新minigame目录重新导入;在坚持 720 版本时暂不上传伪造文件或改版本号。 - 2026-09-02 重新导出后复核
D:\Users\Administrator\Desktop\弹珠接入text_1\720\minigame:根目录game.js为 8,084 bytes、game.json为 654 bytes,wasmcode/de4eef4dc8d1d159.webgl.wasm.code.unityweb.wasm.br为 15,151,684 bytes,已不再是此前的 0/4 字节占位文件;可重新导入微信开发者工具验证。wasmcode/game.js仍为 0 bytes,暂不作为 wasm 二进制完整性判断依据。 - 2026-09-02 16:11 新日志确认 wasm 分包已成功下载并编译;当前失败变为 CDN 首包数据 404。导出目录生成的新文件是
D:\Users\Administrator\Desktop\弹珠接入text_1\720\webgl\64e29d07d6223d9d.webgl.data.unityweb.bin.br(18,045,804 bytes),运行时请求同名文件,但 OSS 720 根目录仍只有旧的97be491cfe81277d.webgl.data.unityweb.bin.br(200),64e29...返回 404。需将新64e29...文件上传到同一 OSS 根目录后再预览;这一步完成前 HotFix/NetController 不会执行。 - 2026-09-02 随后复核 OSS:
64e29d07d6223d9d.webgl.data.unityweb.bin.br已返回 HTTP 200,Content-Length 18,045,804,说明新导出的首包数据已上传成功。可清除微信开发者工具缓存后重新预览,继续观察 HotFix bundle 与GetIpPort日志。 - 2026-09-02 16:18 新日志确认 wasm 与首包数据均已成功下载/解压,但首包初始化后仍按 720 清单请求旧的
c233ed8e38c5d8c785e8244969fba8c7.bundle(mscorlib)并 404。当前本地StreamingAssets/构建报告对应 mscorlib 为26efc0d84c5d4b11e39fb99673983285.bundle,说明重新导出的 data 包与当前 YooAsset bundle 清单未同步;需按“先构建 720 AssetBundle,再导出小游戏,再上传同一批 data、manifest、bundle”的顺序重新生成,不能只替换 OSS data 文件或 TCP 代码。 - 2026-09-02 重新构建/导出并上传后复核 OSS:当前最新 data 文件
b4b7d574128ba5ce.webgl.data.unityweb.bin.br返回 200,大小 18,045,937 bytes;3 个运行时清单和当前构建目录全部 47 个 bundle 共 51 个对象均返回 200,无 404。可清除微信开发者工具全部缓存后重新预览,观察是否进入 HotFix 与 NetController。 - 2026-09-02 16:54 最新预览已使用新
b4b7...data并完成资源包下载/初始化,但随后仍请求c233...bundle404;说明运行时实际加载的 YooAsset 清单仍包含旧 mscorlib 映射,GetIpPort尚未执行。当前应停止修改网络代码,重新核对“同一批 AssetBundle 构建输出→WebGL 导出→manifest/data 上传”的完整链路,或用新的唯一包版本/路径进行缓存隔离。 - 2026-09-02 17:37 新日志确认清单已切换到当前 mscorlib
26efc0d84c5d4b11e39fb99673983285,但 bundle 请求路径为StreamingAssets/yoo/DefaultPackage/<hash>.bundle;此前仅上传 720 根目录 bundle,子路径样例返回 404。需按 WebGL 导出目录保留相对路径,将D:\Users\Administrator\Desktop\弹珠接入text_1\720\webgl\StreamingAssets\yoo\DefaultPackage\下全部.bundle上传到 OSS.../2026-08-28-720/StreamingAssets/yoo/DefaultPackage/,清缓存后重试。 - 2026-09-02 随后复核 OSS 子目录:
StreamingAssets/yoo/DefaultPackage/下本地对应的 47 个 bundle 全部返回 HTTP 200;其中 mscorlib26ef...大小 1,165,915 bytes,HotFixf2f6...大小 267,636 bytes。资源路径现已完整,下一步只需清缓存并重新预览。 - 2026-09-02 最新上传复核:当前本地包版本为
2026-08-28-720-r2;OSS 根目录的PackageManifest_DefaultPackage.version、PackageManifest_DefaultPackage_2026-08-28-720-r2.bytes/.hash和最新 data19a66249237aa142.webgl.data.unityweb.bin.br均返回 HTTP 200,47 个StreamingAssets/yoo/DefaultPackage/*.bundle也全部返回 HTTP 200。上传路径与当前运行时请求路径已匹配。 - 2026-09-02 R3 上传复核:本地版本为
2026-08-28-720-r3;OSS 根目录 version、r3 bytes/hash、最新 data7a69f3891b08fea6.webgl.data.unityweb.bin.br均返回 200,大小分别为 17、7226、32、18051766 bytes;StreamingAssets/yoo/DefaultPackage/下 47 个 bundle 全部返回 200。R3 文件路径完整,可清缓存后预览握手。 - 2026-09-02 微信日志已进入真实 TCP:网关发现成功、
TCPSocket.connect成功、握手请求已发送;服务器返回握手状态码 1(无法识别的平台),随后关闭连接。已将Assets/Scripts/GameLogic/GameController.cs的RuntimePlatform.WebGLPlayer映射为协议平台编号 6;Unity 批处理编译未执行成功,因当前工程已有 Unity 实例占用项目(日志Logs/codex-platform-webgl-compile.log),未结束负责人进程。 - 2026-09-03 网络链路现状:微信正式流程使用
NetController.GetIpPort()的 WebGLUnityWebRequest获取网关地址,不使用直连测试参数;随后由ClientTcpConnectionProbe通过微信TCPSocket执行 ClientGT 握手、游客登录,再发送 ClientPFCLPFGetHeroReq(模块 2/协议 1)并解析CLPFGetHeroAck(模块 2/协议 2)。最新日志已证明网关获取、TCP 建连、游客登录和 GetHero 收包均成功;开发者工具的SystemInfo.deviceUniqueIdentifier返回n/a,探针已回退到PlayerPrefs.DeviceId,并保留临时设备诊断打印。WebGL 导出产生新 data/wasm hash 时,必须同步上传 OSS;YooAsset 资源本身未变时无需单独重建。 - 2026-09-03 最新一次设备回退验证:HTTP 网关、TCP 建连、握手及游客登录请求均执行;设备值已回退为 32 位
PlayerPrefs.DeviceId,但登录请求后未收到可识别的LoginAck,服务器关闭连接,因此没有发送CLPFGetHeroReq。探针新增收包长度、模块/协议号及关闭阶段日志,用于区分服务器无回包与协议号不匹配;重新导出后需提供该段完整日志。Unity 批处理日志Logs/codex-tcp-gethero-diagnose-compile.log仍受打开 Editor 项目锁影响。 - 2026-09-03 登录回归根因已确认:服务器可接受 WebGL
SystemInfo.deviceUniqueIdentifier原始值n/a(此前 23 字节游客登录请求后成功进入 GetHero),但切换为 32 位PlayerPrefs.DeviceId后登录包变为 63 字节并被服务器关闭。探针默认恢复发送原始值以保持已验证链路;新增useFallbackDeviceIdentifierForLogin仅供服务端确认兼容后试用,默认关闭。Unity 批处理日志Logs/codex-tcp-login-device-compat-compile.log仍受打开 Editor 项目锁影响。 - 2026-09-03 已在 PC 端
NetController.SendLoginPlatformReq发送游客登录前增加临时 device 值及长度日志,用于与微信端对比;未改动登录类型、CA3 加密或协议字段。Unity 批处理验证日志为Logs/codex-pc-device-log-compile.log,仍受当前打开的 Editor 项目锁影响。测试后应移除该完整 device 日志。 - 2026-09-03 PC 日志显示成功登录所用 device 为 40 位十六进制;微信使用 32 位
PlayerPrefs.DeviceId时登录被服务器断开。探针回退逻辑已调整为生成/复用 40 位十六进制 SHA-1 值,旧 32 位缓存自动替换;仍需开启useFallbackDeviceIdentifierForLogin后重新导出验证。Unity 批处理日志为Logs/codex-device-40hex-compile.log,仍受 Editor 项目锁影响。 - 2026-09-03 服务端日志确认存在游客设备/会话处理:32 位设备值的两次握手后出现
can't find client session ... OnRecv_PFGTLoginAck;PC 40 位设备值返回errcode:0并分配用户 ID;WebGLn/a返回errcode:0并分配用户 ID;WebGL 40 位设备值也返回errcode:0并分配用户 ID。结论:服务端接受 40 位设备值和n/a,32 位值不兼容;服务端日志尚未包含对应GetHeroReq处理记录,需继续核对登录应答后的连接/英雄请求。 - 2026-09-03 负责人决定不再使用
n/a或随机 40 位设备值;微信探针登录设备字段改为固定纯英文字母常量WebGLMiniGameDeviceIdentifierPinballNode(40 字符、无符号),不再读取SystemInfo/PlayerPrefs。旧回退开关保留但已标记废弃,不参与设备值生成。Unity 批处理日志为Logs/codex-fixed-device-compile.log,仍受打开 Editor 项目锁影响;需重新导出并验证固定值登录及 GetHero 收发。 2026-09-03 编译修复:Assets/Client/Runtime/ClientTcpConnectionProbe.cs原文件存在多处语法截断,导致 CS1622。已恢复为可编译的 TCP 网关/握手/收包最小结构,固定设备值保持不变;完整游客登录与 GetHero 协议发送需在 Unity 编译通过后依据现有 ClientGT/ClientPF 再补回。命令行编译因 Unity 编辑器占用工程未执行到脚本编译,日志Logs/codex-clienttcp-repair-compile.log。 2026-09-03 已补回握手回包后的游客登录请求及登录成功后的CLPFGetHeroReq发送和日志;登录 token 当前为固定设备值的 Base64 占位,需以服务端验证结果确认是否要求 CA3 加密。 2026-09-03 微信日志显示NetController.GetIpPort 不可用,根因是探针只按 HotFix 程序集查找类型;已改为同时查找Assembly-CSharp及所有已加载程序集。需重新 WebGL 构建/转换后验证。 2026-09-03 新日志确认 WebGL IL2CPP 运行时反射仍找不到NetController。已改为直接调用NetController.Instance.GetIpPort,并直接读取SysDefines.Ip/Port,避免裁剪/程序集反射失败。 2026-09-03 修复SysDefines.Port为long与 TCP APIint的 CS0266,加入 1..int.MaxValue 范围校验后显式转换。 2026-09-03 WebGL UnityLinker 报Failed to resolve assembly: HotFix,确认直接引用NetController/SysDefines会使 Assembly-CSharp 产生 HotFix 编译依赖;已移除直接引用,恢复反射查找并在 NetController 尚未初始化时每秒重试。 2026-09-03 已重建Assets/Client/Runtime/ClientTcpConnectionProbe.cs:保留 AOT→HotFix 纯反射边界并用单一协程等待 HotFix/网关;握手补齐平台、产品、版本、device、channel、country、language;游客登录改为CA3Encode(fixedDevice + "," + OpeninstallToken, randomKey)等价实现;登录应答和CLPFGetHeroAck均按ClientGT.cs/ClientPF.cs字段顺序、数组上限和包尾完整校验。状态机只在英雄数据成功解析后请求主动关闭,所有onError、超时、无效包和服务器关闭均输出失败原因。命令行 Unity 编译尝试被已打开的同工程 Editor 项目锁阻止,日志为Logs/codex-tcp-client-session-compile.log;尚未构建、上传或操作 GUI。 2026-09-08 个人中心七页面互斥导航清理:ClientProfileNavigationController改为按个性化五按钮在 ToggleGroup 中的固定顺序映射页面,不再读取旧的持久化跳转目标;从 46 个相关顶部/底部 Toggle 移除旧的序列化GameObject.SetActive回调,避免旧控制器与新控制器并行打开页面;MainPage主页默认恢复激活。GUI 节点、层级、尺寸和位置未改动。Unity 2022.3.57f1c2 批处理验证仍被已打开的同工程 Editor 锁阻止,日志为Logs/codex-profile-route-cleanup-compile.log;需关闭/释放 Editor 后重新编译并运行页面点击回归。 2026-09-08 日志诊断确认旧版控制器存在页面激活重入:ApplyRoute激活页面时触发ToggleGroup.OnEnable,ToggleGroup 又触发导航回调,造成递归ApplyRoute和ArgumentOutOfRangeException。已在ClientProfileNavigationController增加_isApplyingRoute回调抑制,页面切换期间忽略 ToggleGroup 自动初始化事件;日志同时证明七页、21 个顶部 Toggle、25 个底部 Toggle 均已绑定,未绑定数为 0。待负责人重新运行当前脚本后复核。 2026-09-08 根据最新测试日志,顶部 Toggle 在铭牌页可正常返回个人中心,但进入其他个性化页后未观察到后续顶部返回事件;已增加PagesLayerActiveRoots诊断,下一次测试将记录所有仍处于activeInHierarchy的一级页面根节点,用于区分 GUI 点击未命中与页面内容脱离七页根节点。Unity 批处理再次受现有 Editor 实例占用,未结束负责人进程。 2026-09-08 页面导航重构:ClientProfileNavigationController.ApplyRoute改为以PagesLayer为唯一可见性边界,每次切换先关闭PagesLayer下全部一级节点,再只打开目标七页面;这样会同时清理遗留的 MainPage、旧页面和独立包装 Canvas,不再只关闭七页字典中的节点。未修改节点布局和尺寸。Unity 批处理编译日志Logs/codex-profile-route-global-exclusive-compile.log仍显示工程被已有 Editor 占用,待 Editor 空闲后验证。 2026-09-08 通过最新日志和场景结构确认第二套运行时导航:ClientCanvas上的ClientUiNavigator仍订阅旧页面事件并调用ClientUiPage.Enter/Pause/Resume,与新控制器同时改页面状态。已将该场景组件禁用(GUID6f19541d58330684484d3fd37121ff65),保留脚本供旧编辑器工具引用;新控制器作为唯一运行时页面导航入口。验证日志Logs/codex-disable-legacy-ui-navigator-compile.log仍被现有 Unity Editor 项目锁阻止。 2026-09-08 针对负责人最新截图继续收敛页面互斥:运行日志证明当前控制器的PagesLayer一级根节点每次只有一个激活,但画面仍存在重叠,说明可能有旧流程留下的重复页面实例或脱离首次页面字典的同名页面。ClientProfileNavigationController现会扫描当前场景所有位于PagesLayer下的 7 个页面实例,切换时先全部关闭,再打开唯一目标;原有关闭PagesLayer全部一级子节点的保护仍保留,并新增AllPageInstancesActive诊断记录全场景同名页面的实际激活数量。未修改 GUI 尺寸、位置、层级或素材。待负责人重新运行后回传最新[ClientProfileNavigationController] Bind中的allPageInstances数量和截图;Unity 命令行编译需继续在 Editor 释放后执行。 2026-09-08 最新运行日志已确认 7 个页面实例互斥有效(allPageInstances=7、每次AllPageInstancesActive:count=1),但负责人截图仍重叠。因此新增ActiveVisualCanvases诊断,记录ClientCanvas下所有实际启用的 Canvas 路径与排序层级,用于定位页面外 Popup/System 或页面内部独立 Canvas 的第二套显示来源;下一步依据该证据重构唯一显示宿主,不再继续叠加页面SetActive补丁。 2026-09-08 交接记录:负责人要求将当前聊天交接到新聊天。当前页面导航事实:ClientProfileNavigationController日志持续证明 7 个页面互斥,AllPageInstancesActive:count=1;ActiveVisualCanvases显示的 Canvas 全部位于当前激活页面路径下,例如头像/铭牌页自己的Scroll View、默认背景和顶部 Toggle,未发现其他 BadgePage 同级页面同时渲染。Hierarchy 截图也显示 5 个 BadgePage 为PagesLayer下同级节点,当前头像页内部包含Background、Canvas、Scroll View、PersonalizeLabel、默认背景+标签Canvas、个人中心/主页展示/个性化(1)。因此剩余“重叠”尚未被证明是页面导航残留,可能是当前页面内部子节点布局/显隐或运行画面未刷新;未在证据不足时关闭这些内部 Canvas。已禁用场景中的旧ClientUiNavigator,保留旧源码供 Editor 工具引用;顶部/底部旧序列化SetActive回调已清理。最近代码文件为Assets/Client/Runtime/UI/ClientProfileNavigationController.cs,当前 Unity 编译仍被已有 Editor 项目锁阻止,最近日志为Logs/codex-profile-visual-canvas-compile.log。新聊天应先读取本记录、AGENTS.md、相关MODULE.md和最新Editor.log,再决定是否修改 GUI 子节点。 2026-09-08 新目标:负责人暂停 UI 重叠修复,改为在独立ClientShell/Client场景进行服务器数据对接。目标顺序为“建立连接 → 接收原始数据包 → 按模块/协议分类 → 后续再接入各业务接口”,暂不做 UI 展示。已确认不能直接沿用 Boot 的场景生命周期:当前ClientShell没有 Boot 初始化链,现有ClientTcpConnectionProbe仅在微信 WebGL 分支执行。已新增Assets/Client/Runtime/Services/ClientServerPacketRouter.cs,按 ClientGT 1/1、1/5 和 ClientPF 2/1、2/2 分类,输出 JSONL 摘要并可保存本地原始包捕获到Application.persistentDataPath/ClientServerLogs,不写入 UI/业务服务。下一步是增加可替换的 Client 传输适配器:PC 端优先用真实 TCP/网关链路测试,微信端复用同一分类器;不得把真实 token、个人资料或服务端地址写入仓库。当前 Unity 编译仍需在已有 Editor 释放后执行。 2026-09-08 服务器数据对接继续:新增ClientServerPcSession作为 ClientShell 的 PC/Editor 传输入口,通过现有NetController.GetIpPort反射获取网关,不把地址写入仓库;连接后执行握手、游客登录和CLPFGetHeroReq,所有收到的完整包统一送入ClientServerPacketRouter。路由器对CLPFGetHeroAck额外记录英雄/英雄组数量,并识别长度异常与截断包;网关发现增加 15 秒超时。ClientShell 已挂载该入口,WebGL 下自动让位给原微信探针,不改 GUI。命令行验证日志为Logs/codex-client-server-compile.log,仍被已有 Unity Editor 项目锁阻止(HandleProjectAlreadyOpenInAnotherInstance),没有取得脚本编译结果;待负责人重新进入并释放工程后自动重试,编译后等待短暂资源刷新再继续运行验证。 2026-09-08 负责人重新进入 Unity 后,Editor.log 已确认本轮Assembly-CSharp.dll编译成功并完成域重载,未发现本轮error CS;仅有既有未使用字段及旧代码警告。按流程再次执行的命令行验证仍被当前运行的 Unity Editor 拦截,日志为Logs/codex-client-server-compile-retry.log,原因仍是HandleProjectAlreadyOpenInAnotherInstance。下一步可直接在已完成编译的 Unity Editor 中运行ClientShell,观察[ClientServerPC]与[ClientServerData]日志,并把Application.persistentDataPath/ClientServerLogs下的 JSONL 路径/内容回传。 2026-09-08 ClientShell PC 端真实运行验证通过:Editor.log 显示网关解析到临时服务端地址并成功 TCP 建连,发送握手 99 字节、游客登录 71 字节、CLPFGetHeroReq8 字节;收到并分类 3 个服务端包:模块 1/协议 1 握手应答 17 字节、模块 1/协议 5 登录应答 155 字节、模块 2/协议 2 英雄应答 348 字节。JSONL 记录确认HeaderValid,英雄数组 4、英雄组数组 1。原始包与摘要已保存到本地ClientServerLogs,当前目标“连接→收包→分类”闭环完成;下一步再把分类结果映射到可替换的客户端数据接口,暂不接 UI 展示。 2026-09-08 分类可读性增强:ClientServerPacketRouter现在同时记录发送和接收方向;PC 传输每次发送握手、游客登录或CLPFGetHeroReq前均写入分类器。除 JSONL 和原始二进制外,新增同会话.protocol.log,按序号、方向、协议名、模块/协议号、字节数、状态和安全摘要输出,登录令牌等敏感正文不落盘。此前一次运行仍只有 3 个接收包,是因为旧版本只接收记录;需重新运行 ClientShell 生成包含收发双方的新版协议日志。代码修改后待 Unity 编辑器重新编译验证。 2026-09-08 协议分类继续扩展:路由器通过反射扫描已加载的CLGT*、CLPF*类型及其mid/pid常量,自动建立完整协议名目录;记录新增ProtocolName,不再只显示有限枚举。未知或被裁剪的协议仍记录模块/协议号和原始包,不猜测正文。git diff --check未发现空白错误;命令行验证日志Logs/codex-client-protocol-catalog-compile.log仍因 Unity Editor 占用项目而未进入编译。待 Editor 完成本轮自动编译后运行 ClientShell,确认.protocol.log中出现双向及完整协议类名。 2026-09-08 可读分类摘要继续增强:握手请求记录平台/产品/版本,登录请求记录登录方式/令牌长度,握手与登录应答记录状态,英雄应答记录英雄 ID、星级、等级、战力和数组数量;设备、渠道、令牌、密钥、昵称、电话等敏感或个人字段不写日志。发送请求已按请求类别分类,不再显示Unknown。本次命令行日志未生成,说明仍被运行中的 Unity Editor 抢占;待编辑器自动完成本轮编译后重新运行 ClientShell 验证。 2026-09-08 协议日志格式优化:.protocol.log现在按数据包分隔成多行报告,显示发送/接收、协议类名、协议分类、模块中文用途、协议号、长度、校验和字段摘要;字段摘要自动逐项换行,便于人工阅读。未新增接口绑定或 UI 展示逻辑。代码改动后需重新编译并运行一次 ClientShell 才会生成新格式日志。 2026-09-09 微信端协议日志接入:ClientTcpConnectionProbe的握手、游客登录、CLPFGetHeroReq等发送包现在也写入统一ClientServerPacketRouter,微信收到的完整包继续统一分类;可读分段报告同时写入ClientServerLogs并通过 Unity/微信日志输出。未改动 UI 和接口绑定。git diff --check通过;命令行编译因当前 Unity Editor 占用项目被阻止,日志为Logs/codex-wechat-readable-packets-compile.log,待 Editor 自动编译后重新导出微信包验证。 2026-09-09 微信端测试目标确认:负责人要求仅验证 Console 中是否能输出与 PC 相同的双向可读协议报告,测试通过后再移除长期 Console 输出;当前已在微信探针的发送路径调用RecordOutgoing,接收路径调用Accept,并增加 IL2CPP 协议名兜底。最新命令行编译仍被 Editor 锁阻止,需在 Unity Editor 自动编译完成后重新构建/导出微信包并人工回传 Console。