首页/ 第 10 章 · UI 界面系统/ 第 166 课
LESSON 166 · UI 界面系统

UI 拖拽与排序

UI 拖拽已掌握。下一课学 UI 与代码交互。

⏱ 约 14 分钟📊 难度:入门🗂 第 10 章 · UI 界面系统📍 第 166 / 300 课
课程进度
166 / 300

🎯本节学习目标

  • 掌握拖拽接口
  • 实现拖放交换
  • 实现拖动面板

🚀课程导读

“把物品拖进格子”“拖动画板位置”——UI 拖拽用事件系统接口实现。本课掌握。

拖拽基础接口

四个接口搞定拖放。

  1. 实现以下接口(using UnityEngine.EventSystems;):
  2. 【IBeginDragHandler】开始拖:OnBeginDrag(PointerEventData)
  3. 【IDragHandler】拖动中:OnDrag(PointerEventData)
  4. 【IEndDragHandler】结束拖:OnEndDrag(PointerEventData)
  5. 【IDropHandler】被放上:OnDrop(PointerEventData)(目标格子实现)
  6. 【坐标】eventData.position 鼠标位置;拖动物体跟随:
  7. public class DragUI : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
  8. private RectTransform rt;
  9. private Canvas canvas;
  10. void Start() { rt = GetComponent<RectTransform>(); canvas = GetComponentInParent<Canvas>(); }
  11. public void OnDrag(PointerEventData e) {
  12. Vector2 pos;
  13. RectTransformUtility.ScreenPointToLocalPointInRectangle(
  14. canvas.transform as RectTransform, e.position, canvas.worldCamera, out pos);
  15. rt.anchoredPosition = pos;
  16. }
  17. }
  18. 【注意】Canvas 的 Render Mode 会影响坐标转换(Overlay 时 worldCamera 为 null)。
  19. 【拖拽中的图片】拖拽时设置 canvasGroup.blocksRaycasts=false 防止自己挡住目标。
💡
UI 拖拽 = 实现接口 + 坐标转换 + 拖动/放下回调。

拖放交换物品

把物品拖到另一格。

  1. 在物品格子脚本 Slot 上实现 IBeginDragHandler/IDragHandler/IEndDragHandler(拖起自己)+ IDropHandler(被放下)。
  2. 【拖起】OnBeginDrag 记录源格子索引,设置跟随(第 166 课基础)。
  3. 【放下】目标格子的 OnDrop 里读取拖拽中的“源索引”(用一个静态变量传递),交换两个格子的物品数据。
  4. 【静态传递】public static int dragFromIndex = -1; 拖起时设源索引,放下时读取。
  5. 【交换逻辑】
  6. void OnDrop(PointerEventData e) {
  7. if (DragUI.dragFromIndex >= 0 && DragUI.dragFromIndex != myIndex) {
  8. (inventory[myIndex], inventory[DragUI.dragFromIndex]) = (inventory[DragUI.dragFromIndex], inventory[myIndex]);
  9. inventorySystem.RefreshUI();
  10. }
  11. DragUI.dragFromIndex = -1;
  12. }
  13. 【拖拽可视化】拖起时把图标放到一个“临时拖拽层”并跟随鼠标,放下时归位。
  14. 【完成】物品可拖拽交换位置。
  15. 【进阶】拖到“丢弃区”删除物品;拖到“装备格”穿戴。
  16. 【注意】坐标转换与层级(拖拽层在最上层)是细节重点。
拖放交换 = 拖起记录索引 + 放下交换数据 + 刷新 UI。数据与 UI 分离。

常见错误与排查

错误:拖拽时图标不跟随鼠标?
原因:坐标转换错误或 Canvas 模式问题
解决:用 RectTransformUtility.ScreenPointToLocalPointInRectangle 转换;Overlay 模式 worldCamera 传 null。

动手练习

课后小任务(做出来才算真的学会)

  • 实现 UI 元素拖拽跟随鼠标
  • 实现两个格子间的拖放交换
  • (进阶)实现拖拽到丢弃区

本节小结

UI 拖拽已掌握。下一课学 UI 与代码交互。

完成打卡后,主站会实时更新你的学习进度 🎯

← 上一课背包与物品栏 UI