# 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 (挂在 UIRoot,IInputIconService 实现) │ 订阅设备切换事件,切换当前图标集 │ 订阅 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),格式为 `<设备类型>/<控件路径>`。例:`/e`、`/buttonSouth`。**查询时大小写不敏感**。 | | `Icon` | `Sprite` | 对应此绑定路径的按键图标。若为 `null`,`GetIcon()` 返回 `null`,UI 组件通常将图标区域隐藏。 | > **⚠ 重要**:`BindingPath` 是玩家**当前实际绑定**的路径(含改键 `effectivePath`)。若玩家把「交互键」从 `/e` 改到 `/f`,系统查询的是 `/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 键 | `/e` | 交互(Interact) | | F 键 | `/f` | 备用交互 / 拾取 | | R 键 | `/r` | 技能 / 法术 | | 空格 | `/space` | 跳跃(Jump) | | 左 Shift | `/leftShift` | 冲刺(Dash)/ 行走 | | 左 Ctrl | `/leftCtrl` | 下蹲 | | Q 键 | `/q` | 技能槽 1 | | 1-4 数字键 | `/1` … `/4` | 技能快捷栏 | | Tab 键 | `/tab` | 地图 / 物品栏 | | Esc 键 | `/escape` | 暂停菜单 | | 鼠标左键 | `/leftButton` | 攻击(Attack) | | 鼠标右键 | `/rightButton` | 格挡 / 瞄准 | | 鼠标中键 | `/middleButton` | 特殊技能 | | 鼠标滚轮上 | `/scroll/up` | 切换武器 / 技能 | | 鼠标滚轮下 | `/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 键(南键) | `/buttonSouth` | 跳跃 / 确认 | | B 键(东键) | `/buttonEast` | 冲刺 / 取消 | | X 键(西键) | `/buttonWest` | 攻击 / 交互 | | Y 键(北键) | `/buttonNorth` | 技能 / 特殊 | | LB(左肩键) | `/leftShoulder` | 格挡 / 切换 | | RB(右肩键) | `/rightShoulder` | 技能槽 / 切换 | | LT(左扳机) | `/leftTrigger` | 蓄力攻击 / 瞄准 | | RT(右扳机) | `/rightTrigger` | 攻击 / 确认大招 | | 左摇杆按下 | `/leftStickButton` | 冲刺(长按) | | 右摇杆按下 | `/rightStickButton` | 锁定目标 | | Select(菜单左) | `/select` | 物品栏 | | Start(菜单右) | `/start` | 暂停菜单 | | 十字键上 | `/dpad/up` | 上方向 / 选择 | | 十字键下 | `/dpad/down` | 下方向 / 选择 | | 十字键左 | `/dpad/left` | 左方向 / 选择 | | 十字键右 | `/dpad/right` | 右方向 / 选择 | | 左摇杆(上) | `/leftStick/up` | 移动(上) | | 左摇杆(下) | `/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 Settings(Unity Inspector) | 设置项 | 推荐值 | 说明 | |-------|-------|------| | Texture Type | `Sprite (2D and UI)` | 必须设置为 Sprite 类型,否则无法拖入 ObjectField | | Sprite Mode | `Single` | 每个按键一张独立图片,避免拆分 | | Pixels Per Unit | `32` | 与项目统一 PPU,1 像素 = 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`) | | **键鼠图标风格** | 偏向拟物,键盘按键绘制带圆角的方形按键轮廓,鼠标按键绘制鼠标轮廓 | | **手柄图标风格** | 手柄按键使用品牌标准配色:Xbox(A=绿、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(攻击) Xbox:IC_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(如 /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 改键适配说明 **图标集应包含玩家可能绑定到的所有按键**,而非仅包含默认绑定。 例如交互键默认为 `/e`,若玩家将其改为 `/f`,系统查询 `/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(上) | `/w` | W键图标 | | Move(下) | `/s` | S键图标 | | Move(左) | `/a` | A键图标 | | Move(右) | `/d` | D键图标 | | Jump | `/space` | 空格键图标 | | Dash | `/leftShift` | Shift键图标 | | Attack | `/leftButton` | 鼠标左键图标 | | Interact | `/e` | E键图标 | | Map | `/m` | M键图标 | | Pause | `/escape` | Esc键图标 | ### 10.2 Xbox 手柄图标集 — ICN_Xbox | Action 名称 | BindingPath | 建议图标 | |------------|-------------|---------| | Jump | `/buttonSouth` | A键图标(绿) | | Dash | `/buttonEast` | B键图标(红) | | Attack | `/rightTrigger` | RT图标 | | Interact | `/buttonWest` | X键图标(蓝) | | Map | `/select` | View/Select图标 | | Pause | `/start` | Menu/Start图标 | --- ## 十一、修改历史 | 日期 | 修改内容 | |------|---------| | 2026-05-22 | 初版:完整字段说明、BindingPath 参考表、图片规格要求、工作流及排查指南 |