Files

120 lines
5.9 KiB
Markdown
Raw Permalink Normal View History

2026-07-08 19:53:15 +08:00
# 物品使用特殊弹窗 UI 技术参考(左键 Use + DOTween 弹出)
本文档描述“物品左键使用后弹出特殊 UI(Image 从下往上弹出 + 文本展示)”的落地实现、UI 搭建与场景绑定方式。
## 1. 总览
目标:
- 玩家按下左键(Input Action`Use`)使用当前选中背包格子物品
- 若该物品在 `ItemData` 中勾选了 `Show Special Use UI`,则弹出一个 UI 面板(可翻页)
- 面板主体是一个 `Image`,使用 DOTween 从屏幕下方弹出到指定位置
- `Image` 下挂一个 `TMP_Text`(或任意 `TMP_Text` 子节点)用于展示文字
- 面板提供:
- 关闭按钮(手动关闭)
- 上一页/下一页按钮(由配置决定是否出现)
- 通过 `UIPanelStack` 兼容 ESC 关闭(不额外监听 ESC)
- 打开阅读时锁定玩家常规输入并解锁鼠标(通过 `PlayerControlLockService`
- 文字与图片内容由 `ItemData` 配置决定
- 单页:`specialUseUIText``description``displayName`
- 多页:`specialUseUIPages[*].text`
- 图片:`specialUseSprite``icon`
涉及脚本:
- 物品数据:[ItemData.cs](file:///e:/Unity/Unity%20Program/Test_2022/Assets/_Project/Scripts/Inventory/ItemData.cs)
- 使用入口:[ItemUsageSystem.cs](file:///e:/Unity/Unity%20Program/Test_2022/Assets/_Project/Scripts/Player/ItemUsageSystem.cs)
- UI 控制器:[SpecialUsePopupController.cs](file:///e:/Unity/Unity%20Program/Test_2022/Assets/_Project/Scripts/UI/SpecialUsePopupController.cs)
## 2. 调用链(Use → 弹窗)
1) 输入系统触发 `Use`(默认绑定鼠标左键)
2) `ItemUsageSystem.OnUsePerformed``InventorySystem.selectedSlotIndex` 的物品
3) `ItemUsageSystem.UseItem` 根据 `ItemType` 处理使用逻辑
4) 若 `ItemData.showSpecialUseUI == true`:调用 `SpecialUsePopupController.ShowPages(pages, sprite, startIndex)`
注:
- `ItemType.Resource` 默认不可使用;但如果勾选了 `showSpecialUseUI`,则允许“只弹 UI 不消耗”。
- `ItemType.Tool` 当前不做默认逻辑,但同样支持弹 UI(方便做“说明/提示型工具”)。
## 3. ItemData 配置字段(Special Use UI
字段位置:[ItemData.cs](file:///e:/Unity/Unity%20Program/Test_2022/Assets/_Project/Scripts/Inventory/ItemData.cs)
- `showSpecialUseUI`
- 勾选后:该物品在左键 Use 时会弹出特殊 UI
- `useSpecialUseUIPages`
- 勾选后:使用 `specialUseUIPages` 作为分页内容来源
- `specialUseUIPages`
- 每一页的文字内容(不会做“文字超长自动分页”)
-`useSpecialUseUIPages=true` 且列表非空时,会忽略 `specialUseUIText` 的单页文本
- `specialUseUIText`
- 弹窗文字内容
- 为空时 fallback`description``displayName`
- `specialUseSprite`
- 弹窗图片(用于替换 UI Image 的 sprite
- 为空时 fallback`icon`
## 4. UI 结构(推荐)
建议场景中放一个专用 Canvas(也可挂在已有 HUD Canvas 下):
- `SpecialUseCanvas`Canvas
- `SpecialUseRoot`RectTransform,可空,用于收纳)
- `PopupImage`Image + RectTransform
- `PopupText`TextMeshPro - Text
- `CloseButton`Reach Button / ButtonManager
- `PrevPageButton`Reach Button / ButtonManager
- `NextPageButton`Reach Button / ButtonManager
- `SpecialUsePopupController`(脚本,建议挂在 `SpecialUseRoot``PopupImage` 的父级)
要求:
- `PopupImage` 必须是一个 `RectTransform`,用于动画 `DOAnchorPosY`
- 文本必须是 `TMP_Text`TextMeshProUGUI),脚本会自动查找子节点里的第一个 `TMP_Text`
## 5. 场景绑定步骤(最少依赖)
### 5.1 绑定 UI 控制器
1) 将 `SpecialUsePopupController` 挂到 `SpecialUseRoot`(或任意该 Canvas 下的父节点)
2) 在 Inspector 里绑定:
- `Popup Image Rect`:拖入 `PopupImage` 的 RectTransform
- `Popup Image`:拖入 `PopupImage` 的 Image(可不填,脚本会尝试自动找)
- `Popup Text`:拖入 `PopupText`(可不填,脚本会尝试自动找)
- `Close Button`:拖入 `CloseButton`
- `Previous Page Button`:拖入 `PrevPageButton`
- `Next Page Button`:拖入 `NextPageButton`
3) 调整参数:
- `Hidden Y`:面板完全藏到屏幕外时的 Y(通常是负数)
- `Shown Y`:面板弹出后停留的 Y
- `Tween Duration / Tween Ease`
- `Lock Player Control`:打开阅读时是否锁玩家输入并解锁鼠标(推荐开启)
- `Use Panel Stack Escape Close`:是否入 `UIPanelStack` 以支持 ESC 关闭(推荐开启)
### 5.2 绑定物品数据
对需要弹窗的物品 `ItemData`
1) 勾选 `Show Special Use UI`
2) 配置分页方式(二选一):
- 单页:填写 `Special Use UI Text`(或直接使用 `Description` 作为 fallback
- 多页:勾选 `Use Special Use UI Pages`,并在 `Special Use UI Pages` 列表里逐页填写 `Text`
3) (可选)填写 `Special Use Sprite`
### 5.3 使用验证
1) 确保玩家身上有 `ItemUsageSystem` 且 PlayerInput 的 ActionMap 能触发 `Use`
2) 在背包 UI 里选中该物品所在格子(影响 `InventorySystem.selectedSlotIndex`
3) 鼠标左键(Use)应弹出 UI
## 6. 常见问题
- “按左键没反应”
- 检查玩家 `PlayerInput``Use` action 是否存在且绑定到左键
- 检查 `ItemUsageSystem` 是否启用、以及当前 ActionMap 是否为 `Player`
- “弹窗控制器找不到 / Instance 为空”
- 确保场景里存在 `SpecialUsePopupController`
- 如果该对象初始是 Inactive`Awake` 不会执行,`Instance` 不会建立(建议控制器对象保持 Active,让脚本自己在 Awake 里隐藏)
- “按 ESC 没法关闭”
- 确保场景里存在 `UIPanelStack``UIPanelStackInput`(工程通常由 SettingsBootstrap 自动创建)
- 确保控制器勾选了 `Use Panel Stack Escape Close`
- “图片弹出但文字不显示”
- 确保使用的是 TextMeshPro`TMP_Text`),并且 `PopupText``PopupImage` 的子层级中