Unity开箱即用的UGUI面板的拖拽移动功能

发布于:2024-07-01 ⋅ 阅读:(46) ⋅ 点赞:(0)

👉一、背景

之前做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);
        }
    }
}

食用方法:

  1. 直接将DragPanel脚本拖拽赋值给需要拖拽的UI面板。
    在这里插入图片描述

  2. 如果需要拖拽功能的UI面板多,可使用动态绑定方法,该脚本提供了一个Get方法,参数为需要拖拽的对象的RectTransform组件。
    代码动态绑定方法如下:

			RectTransform rectTransform = xxx;//需要赋值,对象不能为空哦。
            DragPanel.Get(rectTransform);

👉五,总结

后续可以进行优化的地方:

  • 鼠标拖拽移动可以是用平滑移动方法
  • 对拖拽范围进行限制

网站公告

今日签到

点亮在社区的每一天
去签到