C#实现对UI元素的拖拽

目录

C#实现对UI元素的拖拽

实现思路

1)按下记录偏移

2)拖动更新位置

为什么要使用offset?

计算逻辑

代码实现

效果

Unity常用UI交互接口


       本篇文章来分享一下对UI元素的拖拽实现。

C#实现对UI元素的拖拽

实现思路

1)按下记录偏移

       鼠标按下时,记录“UI元素锚点” 与“鼠标点击点”的位置差(offset)

2)拖动更新位置

       鼠标移动时,用“鼠标实时位置+偏移量” 更新UI位置,保证UI元素始终跟随鼠标的“抓取点”移动。

为什么要使用offset?

       使用offset是为了让拖拽操作更自然(避免鼠标点击物体时,物体瞬间跳到鼠标位置)。

       若不使用offset,直接把物体位置设为鼠标位置(rectTransform.position = mousePos):当点击物体非中心点(比如左上角)时,物体会瞬间 “瞬移” 到鼠标指针正下方,拖拽手感非常生硬。因为鼠标点击的位置(mousePos)和物体锚点位置(rectTransform.position)通常不在同一位置,直接赋值会导致物体跳位。

计算逻辑

rectTransform.position:物体的锚点位置(默认是物体中心点);

mousePos:鼠标点击时,在世界空间中的指针位置;

offset:两者的差值 = 物体锚点位置 - 鼠标点击位置。

       假设物体锚点在屏幕上的位置是 (100, 200)(rectTransform.position);点击的是物体左上角,此时鼠标位置是 (80, 220)(mousePos);则offset = (100,200) - (80,220) = (20, -20)。此时offset代表:“鼠标点击点”相对于“物体锚点”的偏移量(即锚点在鼠标点击点的右侧20、下方20位置)。

       注意offset只需在OnPointerDown(鼠标按下时)计算一次,之后拖拽过程中保持不变。因为它只需要记录按下瞬间的偏移关系,拖动时复用即可。如果在OnDrag中重复计算,反而会导致物体抖动。

       简而言之,offset就是记住抓住物体的位置,让拖拽时物体跟着抓点走,而不是跳来跳去。

代码实现

using UnityEngine;
using UnityEngine.EventSystems;

public class Drag : MonoBehaviour, IDragHandler, IPointerDownHandler
{
    private RectTransform rectTransform;
    private Vector3 offset;

    private void Awake()
    {
        rectTransform = gameObject.GetComponent<RectTransform>();
    }
    public void OnDrag(PointerEventData eventData)
    {
        if (eventData.pointerPressRaycast.gameObject == gameObject)
        {
            if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out Vector3 mousePos))
            {
                rectTransform.position = mousePos + offset;
            }
        }
    }
    public void OnPointerDown(PointerEventData eventData)
    {
        RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out Vector3 mousePos);
        offset = rectTransform.position - mousePos;
    }
}

效果

Unity常用UI交互接口

接口名称

核心方法

触发时机

使用场景

IPointerDownHandler

OnPointerDown(PointerEventData eventData)

鼠标/触摸按下到UI元素时(触发一次)

拖拽起始记录、长按检测起点、按钮按下反馈

IPointerUpHandler

OnPointerUp(PointerEventData eventData)

鼠标/触摸在UI元素上抬起时(移出元素后抬起不触发)

拖拽结束判定、按钮抬起反馈

IPointerClickHandler

OnPointerClick(PointerEventData eventData)

按下 + 抬起都在同一UI元素上(完整点击,触发一次)

普通按钮点击、UI元素选中

IPointerEnterHandler

OnPointerEnter(PointerEventData eventData)

鼠标/触摸移入UI元素时(触发一次)

悬停提示显示、按钮高亮

IPointerExitHandler

OnPointerExit(PointerEventData eventData)

鼠标/触摸移出UI元素时(触发一次)

悬停提示关闭、按钮高亮取消

IDragHandler

OnDrag(PointerEventData eventData)

拖拽过程中每帧触发(需先按下UI元素)

UI拖拽移动、滑动条拖动、背包物品拖拽

IBeginDragHandler

OnBeginDrag(PointerEventData eventData)

拖拽开始时(按下后首次移动,触发一次)

记录拖拽初始位置、生成拖拽虚影

IEndDragHandler

OnEndDrag(PointerEventData eventData)

拖拽结束时(抬起鼠标/触摸,触发一次)

判定拖拽落点、恢复原UI状态

IScrollHandler

OnScroll(PointerEventData eventData)

鼠标滚轮滚动或触摸滑动时(每帧触发)

自定义滚动视图UI缩放、滚动文本框

ISelectHandler

OnSelect(BaseEventData eventData)

UI元素被选中时(如键Tab切换)

输入框选中高亮、菜单选项选中反馈

IDeselectHandler

OnDeselect(BaseEventData eventData)

UI元素失去选中时(如切换到其他元素)

输入框失去焦点保存内容、取消菜单选中状态

ISubmitHandler

OnSubmit(BaseEventData eventData)

选中UI元素后提交(如按 Enter 键)

菜单确认、表单提交、按钮激活

ICancelHandler

OnCancel(BaseEventData eventData)

触发取消操作时(如按Esc键)

关闭弹窗、取消输入、退出当前界面

       好了,本次的分享到这里就结束啦,希望对你有所帮助~

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值