# V13：原图还原审查与 Unity 位图资源交付约定

审查日期：2026-10-29。范围：R3 三套四屏原图、V12 实际页面与资源生成代码。这里只记录证据与候选制作约定，不表示 V13 美术已经被确认，也不修改游戏业务或发布文件。

## 为什么现在明显对不上

这次的问题成立。当前实现采用了“按参考图重建一套可交互 UI”的方法，交付结果却被当成“把原图独立资源原样装回去”。两者不是同一验收标准。也不能把差异全部归因于网页压缩或说运行时全是矢量。

| 已证实的差异来源 | 本地证据 | 对显示的影响 |
|---|---|---|
| 大部分 UI 外壳重新绘制，而不是原图切片 | `assets/v12/manifest.json` 的 147 条运行资源中，101 条 `native-vector` SVG、46 条 WebP；`source/build_assets_v11.py:16–20` 标注 `native-vector` | 按钮厚度、描边、纹理、爆裂装饰、齿轮轮廓、选中角标只能近似，无法同像素 |
| 原 R3 只被当作参考图保存 | `source/build_assets_v10.py:1–6` 明写原图只供创作参考；`review_slices()` 仅导出预览屏；`art-source/v10/crop-spec.json` 的来源实际是 `generated/*` | 角色、房间、背景虽然是位图，仍是另行生成的素材，并非 R3 原屏每层的原始画素 |
| 标题与按钮字效被系统字体替代 | `source/v12_ui.css:2,5,33` 的系统字体回退与 `text-stroke`；开始战斗仍是 DOM 文字 | 字形、字面宽度、笔画、阴影、字距随字体和平台变化；R3 中的整块艺术字没有原样保留 |
| 按钮与卡框被全方向拉伸 | `build_assets_v11.py:16–20,74–114` 的 `preserveAspectRatio=none` / `stretch=True`；`v12_ui.css:3,5,9,11` 的 `background-size:100% 100%` | 这是整图拉伸，manifest 有 `nineSlice` 字段也不会自动实现九宫格；横竖线宽、圆角和装饰比例一起变化 |
| 状态是新做的 SVG/CSS 组合 | `build_assets_v11.py:100–126` 的 selected/cooling/dead/pressed；`v12_ui.css:23` 的放置预览虚线框/底色 | 状态语义有了，但高光、边框、角点大小与光晕不是原图状态资源；“状态齐全”不等于“状态原样” |
| 暂停、弹框、提示没有对应的正式风格素材 | `v12_ui.css:13,15` 用蓝色纯色面板、CSS 边框、圆角、阴影；`qa/v12/layout/comic-toy-pause.png` 可见 | 外层美漫按钮与通用蓝色设置表单混在一起，形成明显风格断层 |
| 原图与运行画布比例并未统一 | `art-source/v10/review-slices.json`：单屏为 384–429 × 881；`assets/v12/manifest.json`：逻辑画布 432 × 960 | 将两边都强行拉到相同宽高对照，会引入额外形变；不能凭此声称像素对齐或将新拼图偷偷改为原基准 |
| 部分位图还经过有损编码、尺寸归一及裁切布局 | `build_assets_v10.py` WebP quality 88/94；`build_assets_v12.py:42–43,91,106–113` 160px 缩略图/按逻辑格归一/WebP quality 87–90；`v12_ui.css:33` 头像 126% 裁切 | 会改变局部画素或构图，但这是次级差异，不能解释为按钮字效与状态不符的主要原因 |

已目视 `qa/v12/layout/comic-toy-prepare.png`、`comic-toy-pause.png` 及三套 R3：当前“开始战斗”的字形/描边和装饰、首页卡牌框与头像裁切都不同；暂停使用统一蓝色表单。上述结论是实际代码和截图证据，不是对游戏引擎成品的推测。

## 原图与独立资源的边界

现在保存的是扁平合成示意图，不是带图层的 PSD/独立 RGBA 原始资产。可见且完整的矩形区域可以不重画直接裁出；但是被文字、人物、遮挡物覆盖的底板、半透明投影下的背景、看不见的状态，不能从一张图精确恢复。AI 再生成一个近似按钮，也不能称为“原始素材导出”。

正确处理：先保留三套 R3 原图为不可覆盖的比较对象；可完整裁出的原图元素优先原样保留。缺失或不可分离的元素单独列出，补制成候选 RGBA，并在新效果图里明显展示。确认后的独立资源、位置、文字状态共同成为可复现的交付基准；仍保留与旧 R3 的差异清单。任何“像素一致”都要注明比较对象、分辨率和状态。

## 制作与装回的顺序

1. 补三套风格的暂停菜单、二次确认弹框、短提示、玩法帮助、开发者展开与帮助收起状态，以及首页单位锁定。先展示效果图；锁定仅是状态展示，不擅自增加付费或解锁经济规则。
2. 为所有已展示控件准备 `normal / pressed / selected / disabled / locked` 等实际需要的独立图片；战斗卡另有 `cooling / dead`，开关有 `on / off`，折叠条有 `expanded / collapsed`。没有资源的状态列 `missing`，不得用默认矢量悄悄顶替并宣称齐全。
3. 将边框、底色、投影、高光、爆裂装饰作为同一 RGBA 母版的完整画素保存。固定艺术字（例如“开始战斗”、标题、结算词）保留整块位图；中英文各一套。动态金币、弹数、姓名等保留真实数值与固定字体/字形方案，不写死示例数字。
4. 同一份 `resource-contract.json` 记录图片、实际画素尺寸、逻辑尺寸、contentRect、透明边、pivot、坐标、层级、点击区域、语言与状态。网页与 Unity 共同读取或转换这份清单，不再分别“目测实现”。
5. 先以固定参考画布与状态装回一屏；对旧 R3 中未被改动的元素做区域比较，对已确认的新界面用其对应状态参考做比较。位置误差、描边和字效分别验收，通过后再扩到其余屏幕。

## Unity 落地方式（建议，尚未在 Unity 工程验证）

- 美术源交付 RGBA PNG，无损保存。浏览器可另外导出无损 WebP，必须校验解码后 RGBA 与 PNG 一致；PNG 不被覆盖。Unity 不需要为了网页体积将它们改成 SVG。
- 完整按钮/图标/艺术字默认用 `Image` 的 Simple 显示，保持原始比例和明确尺寸；不对爆裂装饰、文字、高光进行任意九宫格拉伸。只有确认允许伸缩的纯面板/边框使用 Sliced，并明确 border。Unity 九宫格保留角区，其他部分仍会变化，因此也不意味着任意尺寸均与原图同像素。[Unity 九宫格](https://learn.unity.com/tutorial/using-9-slicing-for-scalable-sprites?courseId=5dfbdefcedbc2a1fab6019e2)
- 先按现有 432 × 960 逻辑画布建立适配候选，同时保留原 R3 的实际尺寸；正式美术可在相同宽高比以 2×/3×像素制作。`Canvas Scaler` 的 Reference Resolution、缩放策略和锚点统一确定；基准验收在固定分辨率、固定安全区和统一缩放下完成。不同长宽比屏幕需要锚点/安全区适配，不能要求每个物理像素在所有手机上都不变。[Canvas Scaler](https://docs.unity3d.com/Packages/com.unity.ugui@2.0/manual/script-CanvasScaler.html)
- `Canvas Pixel Perfect` 是屏幕空间 UI 的精度选项，不会把不同素材变成同图，也不替代资源/布局对齐。这里是平滑卡通美术，不能为了“像素级”一律开 Point 把图变成锯齿；滤镜应按输出缩放方案验证。[Canvas](https://docs.unity3d.com/Packages/com.unity.ugui@2.0/manual/class-Canvas.html)
- Sprite 导入要保留 alpha、可控 mesh/边界与 pivot。按钮状态采用相同画布/相同 pivot，避免切换时跳动；不要让自动 trim 独立改变每个状态的可见位置。PNG 左上原点坐标转换到 Unity RectTransform 时显式处理方向，不靠图像翻转掩盖错位。[Sprite Editor](https://docs.unity3d.com/cn/2022.2/Manual/sprite-editor-use.html)
- 基准验收使用不缩小 Max Size、无压缩的贴图/图集，确保图集与源的颜色空间、过滤配置一致；平台压缩另做对照。Canvas UI 图集关闭 Allow Rotation，保留明确 padding（官方默认 4px），检查透明边与串色，不以 Tight Packing 代替 UI 矩形契约。[Sprite Atlas](https://docs.unity.com/en-us/engine/6000.0/manual/unity2d/sprite/atlas/sprite-atlas-reference)
- 固定字效用图片最直接；长帮助/动态姓名等使用已选定并具备使用权的字体与 TextMeshPro 资产，字体、字重、大小、材质效果和换行宽度都要交付。没有源字体/准确字图时，不承诺它与原艺术字逐像素一致。[TextMeshPro Font Assets](https://docs.unity3d.com/Packages/com.unity.textmeshpro@4.0/manual/FontAssets.html)

## 验收不可再用“左右看着相近”替代

- 资源级：源 PNG 与网页无损副本解码 RGBA 全量相等；SHA/尺寸/alpha/状态清单完整。SVG 转 PNG 仅改变文件格式，保留的仍是重画后的外观，不能算恢复原稿。
- 基准画布级：同一输出尺寸、色彩空间、语言、单位列表、HP/弹数、选中项和时间点，固定场景与动效，然后输出原图/实拍/差分热图/50%叠图。
- 固定 Sprite 的原生整数位置、同一缩放时可以做逐像素相等检查。跨浏览器与 Unity 抗锯齿、字体渲染、压缩或非整数缩放产生的差异单独记录；不能用宽松总体相似率掩盖按钮字效/细描边的错误。
- 每套风格至少检主界面、搭建、放人、我方战斗、敌方分屏、暂停、确认弹框、帮助、提示、胜负；每页检查正常与相关状态。缺失的 Unity 实机验证明确标记未执行。

## 后续反馈优先于早期示意图的地方

以下变化应保留，不为追 R3 截图而回退：已放置的上方建筑为真正面、下方模板为透视；敌方左/我方右，分屏只分游戏世界，共享 HUD/暂停/卡牌保持不变；只显示真实上场人数；死亡/冷却不可选；仅首页可切语言；未放满也可保存，只让已放置单位开战；胜利失败均有重试与继续；敌方阶段的结束行动保留原位但禁用；短提示和镜头并行；这次新补的锁定状态。

