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