Files
AIC-Project/docs/superpowers/specs/2026-08-04-player-avatar-selection-design.md

143 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 角色属性头像选择设计
## 背景
`Client/Assets/Script/xmain/Module/Player` 下已有角色资料数据、资料存储和 HUD/详情面板。`PlayerProfileData` 已包含 `AvatarId`,但现有界面只显示固定的占位头像,用户无法选择头像。
当前工作区已有 54 张头像资源:
`Client/Assets/Game/Art/UI/Texture/Icon/GamerPic/GamerPic_01.png` `GamerPic_54.png`
本功能在现有角色资料系统上增加头像选择能力,并提供独立的选择界面。
## 目标
- 在角色资料详情中提供“更换头像”入口。
- 展示 54 张可选头像。
- 支持点击头像后即时预览,但只有点击“确认”才保存。
- 确认后同步刷新资料详情、HUD 和其他依赖玩家资料的头像展示。
- 保持已有 `AvatarId = 0` 的旧数据兼容。
- 使用项目现有的异步资源加载、JSON UI 描述和 Prefab 生成规范。
## 非目标
- 不新增头像解锁、付费、分类或搜索功能。
- 不修改角色战斗属性、职业或等级系统。
- 不实现服务端头像保存协议;本次只更新现有客户端 `PlayerProfileStore` 数据。
- 不重构现有 UI 资源目录或处理与本需求无关的工作区资源变更。
## 方案
采用固定 JSON/Prefab 槽位方案,而不是运行时创建网格。
新增 `UI_PlayerAvatarPicker` Dialog 预制体,固定包含 54 个头像槽位。每个槽位直接引用一个 `GamerPic_XX` Sprite,运行时代码只处理选择、高亮、预览和确认。这样布局可在 Unity 编辑器中检查,资源引用稳定,也符合项目 UI 持久化规范。
## 数据与资源
### AvatarId 规则
- `0`:兼容旧存档,显示 `GamerPic_01`
- `1``54`:对应同编号的 `GamerPic_XX`
- 负数或大于 54:显示默认头像,不阻塞界面。
- 用户点击确认后保存 `1``54`
### 资源目录
- 头像:`Client/Assets/Game/Art/UI/Texture/Icon/GamerPic/`
- 通用 UI 资源:使用当前工作区中已有的 `Client/Assets/Game/Art/UI/Texture/UI/Common/` 资源。
- 头像选择预制体:`Client/Assets/Game/Art/UI/Prefab/UI_PlayerAvatarPicker.prefab`
- 头像选择 JSON`Doc/UIPrefabCreater/UI_PlayerAvatarPicker.json`
## 组件边界
### PlayerAvatarCatalog
新增头像目录类,负责:
- 暴露头像数量和默认头像 ID。
- 将头像 ID 转换为 `GamerPic_XX` 资源路径。
- 将旧 ID、负数和超范围 ID 归一化为可显示的默认头像。
目录类不保存玩家状态,也不处理 UI。
### PlayerProfileModule
扩展现有角色资料模块,负责:
- 异步加载并刷新 HUD、详情面板中的头像。
- 绑定详情面板的头像入口。
- 异步打开和关闭头像选择弹窗。
- 持有临时 `pendingAvatarId`,隔离预览状态与已保存资料。
- 更新选择槽位高亮和预览头像。
- 点击确认时更新 `PlayerProfileStore`
异步回调必须校验当前视图仍存在,且回调对应的头像 ID 仍是当前请求,避免关闭界面或快速切换时旧回调覆盖新状态。
### PlayerProfileStore
继续作为玩家资料的唯一状态源。确认头像时通过已有 `Update` 接口修改 `AvatarId`,由 `Changed` 事件驱动所有资料视图刷新。
## 界面设计
### 资料详情面板
- 保留现有昵称、UID、职业、货币和战斗属性布局。
- 头像区域增加可点击的“更换头像”入口。
- 当前头像继续使用头像框包裹,并替换内部固定占位图。
### 头像选择弹窗
挂载到 `UILayer.Dialog`,包含:
- 遮罩层:点击后取消选择。
- 弹窗标题:`选择头像`
- 当前头像预览区:头像框、预览头像和选择提示。
- 可滚动头像列表:6 列 × 9 行,共 54 个头像槽位。
- 每个头像槽位:头像 Image、选中高亮 Image、点击 Button。
- 底部按钮:`取消``确认`
- 右上角关闭按钮:等同取消。
界面使用现有蓝绿描边弹窗、深色文字、TextMeshProUGUI 和通用按钮/列表资源。头像 Image 保持等比显示。
## 交互流程
1. 用户打开角色资料详情。
2. 用户点击头像区域或更换入口。
3. 模块异步加载并实例化头像选择弹窗。
4. 弹窗以当前资料头像初始化 `pendingAvatarId` 和选中态。
5. 用户点击任意头像时,只更新预览和选中高亮。
6. 点击取消、关闭或遮罩时销毁弹窗,不调用 `PlayerProfileStore.Update`
7. 点击确认时调用 `PlayerProfileStore.Update` 保存头像 ID,然后关闭选择弹窗。
8. `PlayerProfileStore.Changed` 触发 HUD、详情面板和头像展示刷新。
## 异常处理
- 头像资源加载失败:保留 `ico_user` 占位头像并记录一次错误日志。
- 头像 ID 非法:按默认头像显示,不抛出 UI 阻塞异常。
- 重复点击打开:只允许一个选择弹窗实例。
- 关闭弹窗后仍返回的异步加载:丢弃回调结果。
## 测试与验收
### EditMode 测试
- 验证头像 ID 到 `GamerPic_XX` 路径的映射。
- 验证 0、负数和超范围 ID 都回退默认头像。
- 验证取消不会触发资料变更事件。
- 验证确认只修改 `AvatarId`,不改变其他资料字段。
- 验证头像变更后资料模块刷新 HUD 与详情视图。
- 验证 `UI_PlayerAvatarPicker.json` 通过 JSON Prefab Builder 校验。
### Unity 编辑器验证
- 头像选择预制体可正常加载。
- 54 个头像槽位排列为 6 列 × 9 行并可滚动。
- 当前头像有选中高亮。
- 点击头像会更新预览但不会提前保存。
- 确认、取消、关闭和遮罩点击行为符合交互流程。
- 确认后的头像同时出现在资料详情和 HUD。
## 验收标准
用户进入角色属性详情后,点击头像可以打开选择界面;选择任意头像可以即时预览但在确认前不保存;点击确认后头像 ID 保存并同步更新详情页和 HUD;取消选择后原头像保持不变。