文章目录
- 👉一、背景
- 👉二、效果图
- 👉三、原理
- 👉四、核心代码
- 👉五,总结
👉一、背景
之前做PC项目时常常有面板拖拽移动的需求,今天总结封装一下,做成一个随时随地可复用的拖拽面板功能。
👉二、效果图
👉三、原理
实现原理也非常简单。首先继承UI事件系统下的两个接口:
IBeginDragHandler, IDragHandler
进而实现两个接口方法即可,主要是在开始拖拽事件里面,记录鼠标按下的坐标mMouseDownPosition和面板的初始坐标mPanelOriginPosition;然后在拖拽过程中鼠标在Canvas下的坐标,减去开始拖拽的鼠标坐标得到一个鼠标坐标偏移量,加上原始面板坐标得到一个新的拖拽位置的坐标,进行坐标赋值即可。
👉四、核心代码
using UnityEngine;
using UnityEngine.EventSystems;
namespace Utility
{
/// <summary>
/// UGUI面板的拖拽移动功能
/// </summary>
[RequireComponent(typeof(RectTransform))]
public class DragPanel : MonoBehaviour, IBeginDragHandler, IDragHandler
{
/// <summary>
/// 静态方法,提供动态绑定拖拽面板的接口
/// </summary>
/// <param name="rectTransform"></param>
/// <returns></returns>
public static DragPanel Get(RectTransform rectTransform)
{
DragPanel dragPanel = rectTransform.gameObject.GetComponent<DragPanel>();
if (dragPanel == null)
{
dragPanel = rectTransform.gameObject.AddComponent<DragPanel>();
}
return dragPanel;
}
/// <summary>
/// 当前拖拽面板的根节点,一般是Canvas
/// </summary>
private RectTransform canvasRect;
private Canvas rootCanvas;
private Camera uiCam;
/// <summary>
/// 是否允许拖拽
/// </summary>
private bool isAllowDrag;
private Vector3 mMouseDownPosition;
private Vector3 mPanelOriginPosition;
private void Awake()
{
Transform root = transform.root;
if (root != null)
{
rootCanvas = root.GetComponent<Canvas>();
canvasRect = root as RectTransform;
if (rootCanvas.renderMode == RenderMode.ScreenSpaceCamera)
{
uiCam = rootCanvas.worldCamera;
}
}
isAllowDrag = rootCanvas != null;
}
public void OnBeginDrag(PointerEventData eventData)
{
if (!isAllowDrag) return;
RectTransformUtility.ScreenPointToWorldPointInRectangle(
canvasRect,
Input.mousePosition,
uiCam,
out mMouseDownPosition);
mPanelOriginPosition = transform.position;
}
public void OnDrag(PointerEventData eventData)
{
if (!isAllowDrag) return;
Vector3 currentMousePosInUGUI;
RectTransformUtility.ScreenPointToWorldPointInRectangle(
canvasRect,
Input.mousePosition,
uiCam,
out currentMousePosInUGUI);
transform.position = mPanelOriginPosition + (currentMousePosInUGUI - mMouseDownPosition);
}
}
}
食用方法:
-
直接将DragPanel脚本拖拽赋值给需要拖拽的UI面板。
-
如果需要拖拽功能的UI面板多,可使用动态绑定方法,该脚本提供了一个Get方法,参数为需要拖拽的对象的RectTransform组件。
代码动态绑定方法如下:
RectTransform rectTransform = xxx;//需要赋值,对象不能为空哦。
DragPanel.Get(rectTransform);
👉五,总结
后续可以进行优化的地方:
- 鼠标拖拽移动可以是用平滑移动方法
- 对拖拽范围进行限制