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

Unity实现IEndDragHandler后OnEndDrag事件隔次触发问题

Unity UGUI OnEndDrag 回调隔次触发问题

问题现象

  • 已实现IEndDragHandler接口,其余拖拽相关回调(IBeginDragHandler、IDragHandler)运行正常,仅OnEndDrag存在隔次触发异常
  • 异常规律固定:首次抓取物体从A点拖拽到B点松开鼠标时,OnEndDrag不会被调用;执行完全相同的第二次拖拽操作时,该回调正常触发,该“一次不触发、一次触发”的循环规律持续存在,并非仅在应用首次启动时出现
  • 初步排查方向:怀疑问题与bool类型状态变量有关,符合隔次触发的典型特征,初步定位怀疑是拖拽处理逻辑关联的dragging布尔标记状态异常,但未检索到其他开发者反馈同类问题。

关联代码

核心拖拽逻辑

public class VideoMovement : MonoBehaviour, IPointerClickHandler, IBeginDragHandler, IDragHandler, IEndDragHandler
    {
        public VideoModule videoModule;
        Camera mainCamera;
        private bool dragging1 = false;
        
        protected void OnEnable()
        {
            mainCamera = Camera.main;
            m_MapMovementListener = GameObject.Find("EditorManagers").GetComponent<MapMovementListener>();
            reSizeArrow = videoModule.transform.GetChild(1).gameObject;
        }

        protected void Update()
        {
            Debug.Log(dragging);
            if (SiteCameraEditor.instance.shouldShowUI)
            {
                SizeManager();
            }
        }

        public void OnBeginDrag(PointerEventData eventData)
        {
            if (SiteCameraEditor.instance.shouldShowUI)
            {
                VisualRepresentationManager(false);
                m_Video_Transform = transform.parent;
                m_VideoInitialPosition_Vector3 = m_Video_Transform.position;
                m_Initial_Position = eventData.pointerCurrentRaycast.worldPosition;
                videoModule.ElementData.Imager.homePresetPoint = m_Video_Transform.position;
                m_Imager = FindImagerWithID(m_Video_Transform.GetComponent<VideoModule>().ElementData.Imager.Id);
                SiteCameraEditor.instance.DrawLine(m_Imager.transform.position, m_Video_Transform.position, Color.red);
                SiteCameraEditor.instance.SelectCamera(m_Video_Transform.GetComponent<VideoModule>().ElementData.Imager.gameObject);
                m_MapMovementListener.SetObjectToMove(this);
            }
        }

        public void OnEndDrag(PointerEventData eventData)
        {
            if(SiteCameraEditor.instance.shouldShowUI)
            {
                VisualRepresentationManager(true);
                Debug.Log("OnEndDrag worked");
                SiteCameraEditor.instance.UpdateUI();
            }
        }

补充说明:上述代码中SiteCameraEditor.instance.shouldShowUI取值始终为true,已删除大部分无关代码,仅保留问题相关逻辑段。

额外Update循环逻辑

类中还包含如下Update逻辑,用于处理UV偏移调整:

protected void Update()
        {
            if (SiteCameraEditor.instance.shouldShowUI)
            {
                SizeManager();
            }
            if(SiteCameraEditor.instance.shouldShowUI && reSizeArrow.activeInHierarchy)
            {
                reSizeArrow.SetActive(false);
            }
            
            try
            {
                if (!dragging1)
                {
                    return;
                }

                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

                Vector3 wolrdSpaceNormal = transform.TransformDirection(Vector3.back);
                Plane moveAxis = new(wolrdSpaceNormal, transform.position);

                if (moveAxis.Raycast(ray, out float intersect))
                {
                    Vector3 movePosition = ray.GetPoint(intersect);

                    Vector3 localClickPosition = transform.parent.transform.InverseTransformPoint(clickPosition);
                    Vector3 localMovePosition = transform.parent.transform.InverseTransformPoint(movePosition);

                    float offsetX = offsetRatioX * (localMovePosition.x - localClickPosition.x);
                    float offsetY = offsetRatioY * (localMovePosition.y - localClickPosition.y);

                    Mesh mesh = GetComponentInChildren<MeshFilter>().mesh;
                    Vector2[] uvs = mesh.uv;

                    float uvsSizeX = originalUVs[1].x - originalUVs[0].x;
                    float uvsSizeY = originalUVs[1].y - originalUVs[0].y;

                    float startX = originalUVs[0].x - offsetX;
                    float endX = originalUVs[1].x - offsetX;
                    float startY = originalUVs[0].y - offsetY;
                    float endY = originalUVs[1].y - offsetY;

                    // X TOO LEFT
                    if (startX <= 0)
                    {
                        startX = 0;
                        endX = startX + uvsSizeX;
                    }
                    // X TOO RIGHT
                    else if (endX >= 1)
                    {
                        endX = 1;
                        startX = endX - uvsSizeX;
                    }
                    // Y TOO DOWN
                    if (startY <= 0)
                    {
                        startY = 0;
                        endY = startY + uvsSizeY;
                    }
                    // X TOO UP
                    else if (endY >= 1)
                    {
                        endY = 1;
                        startY = endY - uvsSizeY;
                    }

                    uvs[0] = new Vector2(startX, startY);
                    uvs[1] = new Vector2(endX, endY);
                    uvs[2] = new Vector2(endX, startY);
                    uvs[3] = new Vector2(startX, endY);
                    mesh.uv = uvs;
                }
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }
        }

已尝试排查操作

  • 将上述UV处理相关的Update逻辑块整体注释后,OnEndDrag隔次不触发的问题仍然存在。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:51:21