You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用IBeginDragHandler保持拖拽位置一致,避免跳转至GameObject中心?

解决Unity拖拽2D物体时指针跳转至中心的问题

嘿,这个问题我之前也碰到过!核心问题是你直接把物体的世界位置绑定到鼠标的屏幕坐标上,既没处理屏幕坐标和世界坐标的转换,也没考虑点击点和物体中心的偏移,所以才会出现拖拽时物体中心突然跳到鼠标位置的尴尬情况。

要解决这个问题,我们只需要在拖拽开始时记录鼠标点击点相对于物体中心的偏移量,之后拖拽过程中用鼠标当前位置结合这个偏移量来更新物体位置,就能保持拖拽的一致性了。下面是修改后的完整代码:

using UnityEngine;
using UnityEngine.EventSystems;

public class Draggable : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    // 存储鼠标点击点与物体中心的偏移量
    private Vector3 _dragOffset;

    public void OnBeginDrag(PointerEventData eventData)
    {
        Debug.Log("Started dragging");
        // 将鼠标屏幕坐标转换为世界坐标(保持Z轴与物体一致,避免2D物体位置偏移)
        Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(eventData.position);
        mouseWorldPos.z = transform.position.z;
        // 计算偏移:物体当前位置 - 鼠标点击的世界位置
        _dragOffset = transform.position - mouseWorldPos;
    }

    public void OnDrag(PointerEventData eventData)
    {
        Debug.Log("Currently dragging");
        // 转换鼠标当前屏幕坐标到世界坐标
        Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(eventData.position);
        mouseWorldPos.z = transform.position.z;
        // 用鼠标位置加上偏移量,让物体跟着点击点移动
        transform.position = mouseWorldPos + _dragOffset;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        Debug.Log("Ended dragging");
    }
}

关键细节说明:

  • 偏移量的作用:_dragOffset记录了你点击物体时,鼠标点和物体中心的距离差。比如你点击物体的右上角,这个偏移量就是中心到右上角的向量,拖拽时用鼠标位置加上这个向量,物体的右上角就会一直跟着鼠标走,不会出现跳转。
  • 坐标转换:eventData.position是屏幕坐标(以像素为单位),而transform.position是世界坐标,必须用Camera.main.ScreenToWorldPoint转换,同时要固定Z轴值,避免2D物体在拖拽时前后移动。
  • 多相机场景适配:如果你的场景里有多个相机,不要依赖Camera.main(它只会找带MainCamera标签的相机),可以在脚本里加一个public Camera uiCamera;变量,把渲染2D物体的相机拖进去,替换代码里的Camera.main。

内容的提问来源于stack exchange,提问作者Pete

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:02:43