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
相关产品推荐
相关产品推荐

