docs: design player avatar selection

This commit is contained in:
ud18010
2026-08-04 14:33:14 +08:00
parent 3ceb9efc05
commit 599ed44ebb
@@ -0,0 +1,142 @@
# 角色属性头像选择设计
## 背景
`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;取消选择后原头像保持不变。