Files
zeling_v2/Docs/Tuning/InputDeviceIconSetSO_Tuning.md
Joywayer e879efaa89 Add InputDeviceIconSetSO configuration guide and related documentation
- Created a new markdown file detailing the configuration of InputDeviceIconSetSO.
- Included sections on system architecture, field explanations, image specifications, and complete workflow from setup to runtime.
- Documented the automatic device recognition logic and provided troubleshooting for common issues.
- Added references to relevant files and scripts for easier navigation.
2026-05-23 00:10:23 +08:00

385 lines
19 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.
# InputDeviceIconSetSO 配置指南
**配置文件**`Assets/_Game/Data/UI/InputIcons/ICN_*.asset`
**对应脚本**`InputDeviceIconSetSO.cs` · `InputIconService.cs` · `InputDeviceDetector.cs`
**创建工具**Unity 菜单 `BaseGames/Input Icon Studio` 或 Inspector 自定义编辑器
**影响系统**`InputIconService` · `InteractPromptWidget` · `InputDeviceIconSwitcher` · `InputIconImage`
---
## 一、系统架构概述
```
InputDeviceDetector (挂在 UIRoot
│ 侦听底层输入事件,识别当前设备类型
│ 广播 InputDeviceTypeEventChannelSO
InputIconService (挂在 UIRootIInputIconService 实现)
│ 订阅设备切换事件,切换当前图标集
│ 订阅 InputSystem.onActionChange改键后刷新
│ SerializeField 直接持有 4 套 InputDeviceIconSetSO 引用
├── _kbMouseSet → ICN_KeyboardMouse.asset
├── _xboxSet → ICN_Xbox.asset
├── _playStationSet → ICN_PlayStation.asset
└── _switchSet → ICN_Switch.asset
InputDeviceIconSetSO
├── _deviceType (编辑器标识,匹配工具过滤)
└── _entries[] (绑定路径 → Sprite 的映射表)
GetIcon(bindingPath) → Sprite?
UI 消费层
├── InteractPromptWidget 按键提示 HUD 组件
├── InputDeviceIconSwitcher 静态 Sprite 切换(不随改键变化)
└── InputIconImage 动态图标(支持 ByActionName 模式,随改键自动刷新)
```
**核心原则**
`InputDeviceIconSetSO` 是**纯数据容器**,本身无运行时逻辑;查询、缓存、刷新均由 `InputIconService` 负责。每套 SO 对应一个输入设备,相互独立,方便美术分别维护。
---
## 二、InputDeviceIconSetSO 字段详解
### 2.1 顶层字段
| 字段 | 类型 | 序列化名 | 说明 |
|------|------|---------|------|
| Device Type | `InputDeviceType` 枚举 | `_deviceType` | 标识本图标集对应的设备类型。**不影响运行时选择逻辑**(选择由 `InputIconService` 按字段引用决定但供编辑器工具Input Icon Studio过滤、分组显示。 |
| Entries | `IconEntry[]` 数组 | `_entries` | 全部绑定路径与图标的映射表,核心数据。数组顺序不影响查询结果(逐项遍历大小写不敏感匹配)。 |
### 2.2 IconEntry 结构体字段
每个 `IconEntry` 表示"当玩家的某个按键绑定在 `BindingPath` 时,应显示 `Icon` 这张图标"。
| 字段 | 类型 | 说明 |
|------|------|------|
| `BindingPath` | `string` | Unity InputSystem 的**绑定路径**Binding Path格式为 `<设备类型>/<控件路径>`。例:`<Keyboard>/e``<Gamepad>/buttonSouth`。**查询时大小写不敏感**。 |
| `Icon` | `Sprite` | 对应此绑定路径的按键图标。若为 `null``GetIcon()` 返回 `null`UI 组件通常将图标区域隐藏。 |
> **⚠ 重要**`BindingPath` 是玩家**当前实际绑定**的路径(含改键 `effectivePath`)。若玩家把「交互键」从 `<Keyboard>/e` 改到 `<Keyboard>/f`,系统查询的是 `<Keyboard>/f`,因此图标集中**需要包含全部玩家可能绑到的按键**,否则改键后图标显示为空。
---
## 三、Device Type 枚举说明
| 枚举值 | 含义 | 对应 InputIconService 字段 |
|--------|------|--------------------------|
| `KeyboardMouse` | 键盘 + 鼠标 | `_kbMouseSet` |
| `XboxController` | Xbox 手柄XInput、PC 通用手柄 | `_xboxSet` |
| `PlayStationController` | PS4 DualShock 4 / PS5 DualSense | `_playStationSet` |
| `SwitchController` | Switch Pro Controller / Joy-Con | `_switchSet` |
`InputDeviceDetector` 通过 `InputSystem.IsFirstLayoutBasedOnSecond` 检测布局层次来精确识别设备类型:
- DualShockGamepad / DualSenseGamepad → `PlayStationController`
- XInputController → `XboxController`
- 其他未知手柄 → 默认 `XboxController`Xbox 图标最通用)
---
## 四、BindingPath 完整参考表
### 4.1 键鼠KeyboardMouse— 常用按键路径
| 按键 | BindingPath | 常见用途 |
|------|-------------|---------|
| E 键 | `<Keyboard>/e` | 交互Interact |
| F 键 | `<Keyboard>/f` | 备用交互 / 拾取 |
| R 键 | `<Keyboard>/r` | 技能 / 法术 |
| 空格 | `<Keyboard>/space` | 跳跃Jump |
| 左 Shift | `<Keyboard>/leftShift` | 冲刺Dash/ 行走 |
| 左 Ctrl | `<Keyboard>/leftCtrl` | 下蹲 |
| Q 键 | `<Keyboard>/q` | 技能槽 1 |
| 1-4 数字键 | `<Keyboard>/1``<Keyboard>/4` | 技能快捷栏 |
| Tab 键 | `<Keyboard>/tab` | 地图 / 物品栏 |
| Esc 键 | `<Keyboard>/escape` | 暂停菜单 |
| 鼠标左键 | `<Mouse>/leftButton` | 攻击Attack |
| 鼠标右键 | `<Mouse>/rightButton` | 格挡 / 瞄准 |
| 鼠标中键 | `<Mouse>/middleButton` | 特殊技能 |
| 鼠标滚轮上 | `<Mouse>/scroll/up` | 切换武器 / 技能 |
| 鼠标滚轮下 | `<Mouse>/scroll/down` | 切换武器 / 技能 |
> 完整键盘路径参考 Unity InputSystem 文档:[Keyboard Control Path](https://docs.unity3d.com/Packages/com.unity.inputsystem@latest/index.html?subfolder=/manual/Controls.html)
### 4.2 Xbox 手柄XboxController— 全按键路径
| 按键名称 | BindingPath | 说明 |
|---------|-------------|------|
| A 键(南键) | `<Gamepad>/buttonSouth` | 跳跃 / 确认 |
| B 键(东键) | `<Gamepad>/buttonEast` | 冲刺 / 取消 |
| X 键(西键) | `<Gamepad>/buttonWest` | 攻击 / 交互 |
| Y 键(北键) | `<Gamepad>/buttonNorth` | 技能 / 特殊 |
| LB左肩键 | `<Gamepad>/leftShoulder` | 格挡 / 切换 |
| RB右肩键 | `<Gamepad>/rightShoulder` | 技能槽 / 切换 |
| LT左扳机 | `<Gamepad>/leftTrigger` | 蓄力攻击 / 瞄准 |
| RT右扳机 | `<Gamepad>/rightTrigger` | 攻击 / 确认大招 |
| 左摇杆按下 | `<Gamepad>/leftStickButton` | 冲刺(长按) |
| 右摇杆按下 | `<Gamepad>/rightStickButton` | 锁定目标 |
| Select菜单左 | `<Gamepad>/select` | 物品栏 |
| Start菜单右 | `<Gamepad>/start` | 暂停菜单 |
| 十字键上 | `<Gamepad>/dpad/up` | 上方向 / 选择 |
| 十字键下 | `<Gamepad>/dpad/down` | 下方向 / 选择 |
| 十字键左 | `<Gamepad>/dpad/left` | 左方向 / 选择 |
| 十字键右 | `<Gamepad>/dpad/right` | 右方向 / 选择 |
| 左摇杆(上) | `<Gamepad>/leftStick/up` | 移动(上) |
| 左摇杆(下) | `<Gamepad>/leftStick/down` | 移动(下) |
### 4.3 PlayStation 手柄
PS 手柄的**面板按键路径与 Xbox 完全相同**`buttonSouth/East/West/North`)。底层 InputSystem 通过布局映射统一了方向标识:
| 逻辑路径 | Xbox 对应 | PlayStation 对应 |
|---------|----------|----------------|
| `buttonSouth` | A | ✕ Cross |
| `buttonEast` | B | ○ Circle |
| `buttonWest` | X | □ Square |
| `buttonNorth` | Y | △ Triangle |
| `leftShoulder` | LB | L1 |
| `rightShoulder` | RB | R1 |
| `leftTrigger` | LT | L2 |
| `rightTrigger` | RT | R2 |
| `select` | Select / View | Share / Create |
| `start` | Start / Menu | Options |
> **关键设计点**XboxController 和 PlayStationController 共享相同的 `BindingPath` 字符串,各自在**不同的 `InputDeviceIconSetSO`** 中映射到对应视觉风格的按键图标Xbox 用圆形彩色图标PS 用特殊符号图标),由 `InputIconService` 根据当前设备选择哪套 SO。
### 4.4 Switch 手柄
Switch Pro Controller 路径与 Xbox/PS 相同,面板按键按 Nintendo 习惯排列:
| 逻辑路径 | Switch 对应 |
|---------|------------|
| `buttonSouth` | B |
| `buttonEast` | A |
| `buttonWest` | Y |
| `buttonNorth` | X |
| `leftShoulder` | L |
| `rightShoulder` | R |
| `leftTrigger` | ZL |
| `rightTrigger` | ZR |
| `select` | - |
| `start` | + |
> ⚠ **Switch 按键位置与 Xbox/PS 习惯相反**(南键是 B 不是 A美术制作图标时需注意
> `buttonSouth` 图标应画 **B**(而非 A`buttonEast` 图标应画 **A**(而非 B
---
## 五、图片Sprite规格要求
### 5.1 推荐尺寸
| 用途 | 推荐尺寸 | 说明 |
|------|---------|------|
| 标准按键图标HUD/提示 UI | **32×32 px** | InteractPromptWidget 默认显示尺寸32px 在像素风格下清晰无锯齿 |
| 高分辨率版本(设置界面、教程) | **64×64 px** | 用于放大显示的场合,需额外维护一套 |
| 复合按键图标LT+RT、双摇杆 | **48×24 px****64×32 px** | 横向组合按键,宽高比 2:1 |
### 5.2 Import SettingsUnity Inspector
| 设置项 | 推荐值 | 说明 |
|-------|-------|------|
| Texture Type | `Sprite (2D and UI)` | 必须设置为 Sprite 类型,否则无法拖入 ObjectField |
| Sprite Mode | `Single` | 每个按键一张独立图片,避免拆分 |
| Pixels Per Unit | `32` | 与项目统一 PPU1 像素 = 1/32 unit |
| Filter Mode | `Point (no filter)` | 像素风格固定值,避免双线性插值导致模糊 |
| Compression | `None`(开发),发布时 `ASTC 6x6`(移动端)| UI 图标质量要求高,开发期不压缩 |
| Generate Mip Maps | `关闭` | 2D UI 不需要 Mip Maps |
| Read/Write Enabled | `关闭` | 不需要像素读写 |
| Max Size | `128` | 32px 图标不需要超过 128 |
| Wrap Mode | `Clamp` | 避免边缘溢出 |
### 5.3 美术风格规范
| 规范项 | 说明 |
|-------|------|
| **背景透明** | 必须使用 PNG 格式,透明通道保存完整,不要有白色/黑色底边 |
| **视觉安全区** | 图标主体保留 2px 内边距,避免内容贴近边缘被裁剪 |
| **明度/对比度** | 图标应在深色(`rgba(0,0,0,0.85)`)背景上清晰可见;避免使用纯黑色线条(改用深灰 `#222` |
| **键鼠图标风格** | 偏向拟物,键盘按键绘制带圆角的方形按键轮廓,鼠标按键绘制鼠标轮廓 |
| **手柄图标风格** | 手柄按键使用品牌标准配色XboxA=绿、B=红、X=蓝、Y=黄PS✕=蓝、○=红、□=粉、△=绿Switch 使用黑底圆形字母 |
| **一致性** | 同一设备下所有图标使用相同的线条粗细、阴影效果、发光效果 |
### 5.4 文件命名规范
格式:`IC_Key_{DeviceShort}_{KeyName}.png`
| 示例路径 | 对应按键 |
|---------|---------|
| `_Game/Art/UI/Icons/InputKeys/IC_Key_KBM_E.png` | 键盘 E 键 |
| `_Game/Art/UI/Icons/InputKeys/IC_Key_KBM_Space.png` | 键盘空格键 |
| `_Game/Art/UI/Icons/InputKeys/IC_Key_KBM_LMB.png` | 鼠标左键 |
| `_Game/Art/UI/Icons/InputKeys/IC_Key_KBM_RMB.png` | 鼠标右键 |
| `_Game/Art/UI/Icons/InputKeys/IC_Key_Xbox_A.png` | Xbox A 键 |
| `_Game/Art/UI/Icons/InputKeys/IC_Key_Xbox_RT.png` | Xbox RT 扳机 |
| `_Game/Art/UI/Icons/InputKeys/IC_Key_PS_Cross.png` | PS ✕ 键 |
| `_Game/Art/UI/Icons/InputKeys/IC_Key_PS_R2.png` | PS R2 扳机 |
| `_Game/Art/UI/Icons/InputKeys/IC_Key_Switch_B.png` | Switch B 键(南键) |
| `_Game/Art/UI/Icons/InputKeys/IC_Key_Switch_ZR.png` | Switch ZR 扳机 |
---
## 六、InputIconService 绑定配置
`InputIconService` 是图标集的运行时持有者,挂载在 Persistent 场景的 UIRoot 上。其 Inspector 字段:
| 字段 | 类型 | 说明 |
|------|------|------|
| `_inputReader` | `InputReaderSO` | 用于查询 Action 的绑定路径(`GetActionEffectivePath` |
| `_kbMouseSet` | `InputDeviceIconSetSO` | **键鼠图标集**,当检测到键盘/鼠标输入时激活 |
| `_xboxSet` | `InputDeviceIconSetSO` | **Xbox 图标集**,检测到 XInput 手柄时激活;未配置时自动 fallback 至 `_kbMouseSet` |
| `_playStationSet` | `InputDeviceIconSetSO` | **PlayStation 图标集**,检测到 DualShock/DualSense 时激活;未配置时 fallback 至 `_kbMouseSet` |
| `_switchSet` | `InputDeviceIconSetSO` | **Switch 图标集**,检测到 Switch Pro/Joy-Con 时激活;未配置时 fallback 至 `_kbMouseSet` |
| `_onDeviceChanged` | `InputDeviceTypeEventChannelSO` | 设备切换事件频道(`EVT_InputDeviceChanged.asset`),与 `InputDeviceDetector` 共用 |
> **Fallback 策略**:若对应设备图标集为 `null`,自动 fallback 至键鼠集。这意味着开发初期只配置 `_kbMouseSet` 即可正常运行,手柄图标集可后续补充,不影响功能。
---
## 七、UI 消费组件说明
### 7.1 InteractPromptWidget按键提示 HUD
| 配置项 | 说明 |
|-------|------|
| `_promptChannel` | 引用 `InteractPromptEventChannelSO`,订阅 `InteractableDetector` 的广播 |
| 显示逻辑 | 收到事件后查询 `IInputIconService.GetActionIcon(actionName)`,设置图标 Sprite若图标为 `null` 则隐藏图标容器,仅显示文字 |
| 刷新时机 | 设备切换(`OnIconSetChanged`)、改键(`BoundControlsChanged`)时自动重绘 |
### 7.2 InputIconImage动态图标 Image 组件)
`InputIconImage` 是挂载在任意 `Image` 组件旁的辅助脚本,通过 `ServiceLocator` 获取 `IInputIconService`,支持两种工作模式:
| LookupMode | 说明 |
|-----------|------|
| `ByActionName` | **推荐**。指定 Action 名称(如 `"Interact"``"Jump"`),自动查询当前设备+改键后的有效图标 |
| `ByBindingPath` | 固定路径,不随改键变化。适用于「始终显示空格键图标」等特定场景 |
### 7.3 InputDeviceIconSwitcher静态图标切换
| 字段 | 说明 |
|------|------|
| `_kbmSprite` | 键鼠时显示的 Sprite |
| `_xboxSprite` | Xbox 手柄时显示的 Sprite |
| `_psSprite` | PS 手柄时显示的 Sprite |
| `_switchSprite` | Switch 手柄时显示的 Sprite |
适用于「图标固定、仅需在设备间切换整套外观」的场景(如教程截图、设置界面设备标识)。
**不支持改键响应**,如需改键后自动更新请用 `InputIconImage`ByActionName 模式)。
---
## 八、完整配置工作流
### 8.1 快速开始(最小可用配置)
```
1. 准备图片
放入 _Game/Art/UI/Icons/InputKeys/
至少准备以下按键(根据实际绑定按需增删):
键鼠IC_Key_KBM_E.png交互、IC_Key_KBM_Space.png跳跃、IC_Key_KBM_LMB.png攻击
XboxIC_Key_Xbox_X.png交互、IC_Key_Xbox_A.png跳跃、IC_Key_Xbox_RT.png攻击
2. 创建图标集 SO
菜单 BaseGames/Input Icon Studio → 选择键鼠标签页 → 点击「指定图标集」→「新建...」
保存至 _Game/Data/UI/InputIcons/ICN_KeyboardMouse.asset
重复创建 ICN_Xbox.asset
3. 填充映射
在 Input Icon Studio 中:
a. 左侧选中 Action如 Interact
b. 右侧确认 BindingPath如 <Keyboard>/e
c. 将 IC_Key_KBM_E.png 拖入 Sprite 字段
d. 切换到 Xbox 标签,重复上述步骤
4. 绑定到 InputIconService
在 Persistent 场景 UIRoot → InputIconService Inspector 中:
将 ICN_KeyboardMouse.asset 拖入 _kbMouseSet 字段
将 ICN_Xbox.asset 拖入 _xboxSet 字段
5. 验证
进入 PlayMode → 按 E 键 → 观察 HUD 交互提示出现键盘图标
连接手柄 → 观察图标自动切换为 Xbox 图标
```
### 8.2 批量填充工作流(大量按键)
```
1. 在 ICN_KeyboardMouse.asset 的 Inspector 中:
点击「从 Action Asset 填充路径」
→ 自动为 Gameplay ActionMap 中所有 Keyboard&Mouse 绑定生成 Entry路径已填入Icon 为空)
2. 将对应 Sprite 批量拖入各 Entry 的 Icon 字段
(可用 Input Icon Studio 左列的覆盖率指示点确认进度)
3. 在 Input Icon Studio 查看总覆盖率:
标签栏显示 "🖱 键鼠 N/N" — N/N 表示全部配置完成
```
### 8.3 改键适配说明
**图标集应包含玩家可能绑定到的所有按键**,而非仅包含默认绑定。
例如交互键默认为 `<Keyboard>/e`,若玩家将其改为 `<Keyboard>/f`,系统查询 `<Keyboard>/f`,图标集中需有该条目才能正确显示。
**推荐策略**:为键盘图标集预填充全部 26 个字母键 + 常用功能键,为手柄图标集预填充所有面板按键和扳机键。
---
## 九、调试与常见问题排查
| 现象 | 原因 | 解决方案 |
|------|------|---------|
| 图标区域不显示(空白/隐藏) | `BindingPath` 未在图标集中找到匹配条目 | 在 Input Icon Studio 确认该 Action 当前绑定路径,并在图标集中添加对应条目 |
| 切换设备后图标没有变化 | `InputDeviceDetector``InputIconService` 未在场景中激活 | 确认 Persistent 场景 UIRoot 上挂载了两个组件,且 `_onDeviceChanged` 字段引用正确 |
| 改键后图标仍显示旧按键 | 使用的是 `InputDeviceIconSwitcher` 而非 `InputIconImage(ByActionName)` | 改用 `InputIconImage` 组件并设置 `LookupMode = ByActionName` |
| 所有设备均显示键鼠图标 | 手柄图标集字段为 null触发了 fallback 逻辑 | 在 InputIconService Inspector 中为手柄字段指定对应 SO |
| 图标显示模糊 | Import Settings 的 Filter Mode 不正确 | 将所有按键图标的 Filter Mode 改为 `Point (no filter)` |
| 图标有白色边缘 | 导出时 PNG 透明通道处理不正确 | 用 Photoshop/Aseprite 重新导出,确保「直接 Alpha」Straight Alpha而非预乘 Alpha |
| 手柄图标显示 Xbox 风格,但玩家用的是 PS 手柄 | `InputDeviceDetector` 未能识别 DualShock 布局 | 确保 Input System 包含 PS 设备支持(`com.unity.inputsystem` ≥ 1.4),并在 Player Settings 中勾选 DualShock 支持 |
| Input Icon Studio 左列 Action 为空 | `InputReaderSO` 未填入,或 `_inputActions` 字段名不匹配 | 在工具栏 InputReaderSO 字段指定资产;若字段名有变更,同步更新 `InputIconStudioWindow.ReloadActionAsset()` 中的 `FindProperty("_inputActions")` |
---
## 十、推荐图标集最小条目清单
以下是按项目实际 Gameplay ActionMap 中的 Actions 推荐配置的最小图标集。
### 10.1 键鼠图标集 — ICN_KeyboardMouse
| Action 名称 | 默认 BindingPath | 建议图标 |
|------------|-----------------|---------|
| Move | `<Keyboard>/w` | W键图标 |
| Move | `<Keyboard>/s` | S键图标 |
| Move | `<Keyboard>/a` | A键图标 |
| Move | `<Keyboard>/d` | D键图标 |
| Jump | `<Keyboard>/space` | 空格键图标 |
| Dash | `<Keyboard>/leftShift` | Shift键图标 |
| Attack | `<Mouse>/leftButton` | 鼠标左键图标 |
| Interact | `<Keyboard>/e` | E键图标 |
| Map | `<Keyboard>/m` | M键图标 |
| Pause | `<Keyboard>/escape` | Esc键图标 |
### 10.2 Xbox 手柄图标集 — ICN_Xbox
| Action 名称 | BindingPath | 建议图标 |
|------------|-------------|---------|
| Jump | `<Gamepad>/buttonSouth` | A键图标绿 |
| Dash | `<Gamepad>/buttonEast` | B键图标 |
| Attack | `<Gamepad>/rightTrigger` | RT图标 |
| Interact | `<Gamepad>/buttonWest` | X键图标 |
| Map | `<Gamepad>/select` | View/Select图标 |
| Pause | `<Gamepad>/start` | Menu/Start图标 |
---
## 十一、修改历史
| 日期 | 修改内容 |
|------|---------|
| 2026-05-22 | 初版完整字段说明、BindingPath 参考表、图片规格要求、工作流及排查指南 |