120 lines
5.9 KiB
Markdown
120 lines
5.9 KiB
Markdown
# 物品使用特殊弹窗 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` 的子层级中
|