文章目錄
- 👉一、背景
- 👉二、效果圖
- 👉三、原理
- 👉四、核心代碼
- 👉五,總結
👉一、背景
之前做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);
👉五,總結
后續可以進行優化的地方:
- 鼠標拖拽移動可以是用平滑移動方法
- 對拖拽范圍進行限制