直接上代码
using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; namespace Script { class UIDragMover : MonoBehaviour { public Image Body;//ui元素的本体, panel等 public RectTransform CanvasRectangle; //image所在的画布 private bool dragging; private Vector2 targetPosition;//移动时目标位置 private Vector2 offset;//开始移动前记录鼠标与body之间的偏移距离 public void Update() { if (dragging) { //以0.5倍的单位将ui向目标位置移动 Body.rectTransform.anchoredPosition += (targetPosition - Body.rectTransform.anchoredPosition) * 0.5f; } } public void OnBeginDrag(BaseEventData baseEventData) { PointerEventData pointerEventData = baseEventData as PointerEventData; RectTransformUtility.ScreenPointToLocalPointInRectangle( CanvasRectangle, pointerEventData.position, pointerEventData.pressEventCamera, out offset); //计算偏移量 offset = Body.rectTransform.anchoredPosition-offset; dragging = true; } public void OnDrag(BaseEventData baseEventData) { PointerEventData pointerEventData = baseEventData as PointerEventData; RectTransformUtility.ScreenPointToLocalPointInRectangle( CanvasRectangle, pointerEventData.position, pointerEventData.pressEventCamera, out targetPosition); //更新目标位置 targetPosition = targetPosition + offset; } public void OnEndDrag(BaseEventData baseEventData) { dragging = false; } } }
如何使用呢?
首先,Hierarchy中新建画布,画布中添加你所需要的ui部件,这里以panel示例,添加画布会自动添加EventSystem
然后把本脚本拖到Panel上,Body就是你所需要拖拽移动的对象,在本例就是panel,CanvasRectangle是Body所在的画布
然后给Panel添加EventTrigger组件,分别添加BeginDrag、Drag、EndDrag三种事件类型
给每个事件类型添加回调,把Panel(也就是挂脚本的ui元素)拖动1位置,在2位置选择回调函数
这就完成了。
为什么要在Update里进行移动呢,没错完全可以在OnDrag里最后写一句这个然后删掉Update完事
Body.rectTransform.anchoredPosition=targetPosition;
但实际拖动会感到卡顿,Update里进行逐步的移动会增加流畅感。