Unity用鼠标拖拽UI,UI跟随鼠标移动
  v5bEezpf7PPs 2023年11月02日 29 0

@TOC


效果

先上效果

Unity用鼠标拖拽UI,UI跟随鼠标移动_偏移量


一、原理

继承几个拖拽的接口 IBeginDragHandler, IDragHandler,IEndDragHandler 计算下偏移量,转换下坐标系 限制下可拖拽的范围,我设置的是canvas的大小

二、源码

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.EventSystems;

namespace HHQ
{
    /// <summary>
    /// 拖拽ui(限制拖拽范围)
    /// </summary>
    public class LimitUIDrag : MonoBehaviour, IBeginDragHandler, IDragHandler,IEndDragHandler
    {
        /// <summary>
        /// 限制的区域
        /// </summary>
        private RectTransform limitContainer;

        private Canvas canvas;

        private  RectTransform rt;

        // 位置偏移量
        Vector3 offset = Vector3.zero;

        // 最小、最大X、Y坐标
        float minX, maxX, minY, maxY;

        void Start()
        {
            rt = GetComponent<RectTransform>();
            canvas = GetComponentInParent<Canvas>();
            limitContainer = canvas.GetComponent<RectTransform>();
        }

        /// <summary>
        /// 开始拖拽
        /// </summary>
        /// <param name="eventData"></param>
        public void OnBeginDrag(PointerEventData eventData)
        {
            if (eventData.button != PointerEventData.InputButton.Left)
                return;
            if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.enterEventCamera, out Vector3 globalMousePos))
            {
                // 计算偏移量
                offset = rt.position - globalMousePos;
                // 设置拖拽范围
                SetDragRange();
                //EventDispatcher.GameEvent.DispatchEvent(101);
            }
        }

        /// <summary>
        /// 拖拽中
        /// </summary>
        /// <param name="eventData"></param>
        public void OnDrag(PointerEventData eventData)
        {
            if (eventData.button != PointerEventData.InputButton.Left)
                return;
            // 将屏幕空间上的点转换为位于给定RectTransform平面上的世界空间中的位置
            if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.pressEventCamera, out Vector3 globalMousePos))
            {
                rt.position = DragRangeLimit(globalMousePos + offset);
            }
        }
        /// <summary>
        /// 拖拽结束
        /// </summary>
        /// <param name="eventData"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void OnEndDrag(PointerEventData eventData)
        {
            //EventDispatcher.GameEvent.DispatchEvent(103);
        }

        // 设置最大、最小坐标
        void SetDragRange()
        {
            // 最小x坐标 = 容器当前x坐标 - 容器轴心距离左边界的距离 + UI轴心距离左边界的距离
            minX = limitContainer.position.x
                   - limitContainer.pivot.x * limitContainer.rect.width * canvas.scaleFactor
                   + rt.rect.width * canvas.scaleFactor * rt.pivot.x;
            // 最大x坐标 = 容器当前x坐标 + 容器轴心距离右边界的距离 - UI轴心距离右边界的距离
            maxX = limitContainer.position.x
                   + (1 - limitContainer.pivot.x) * limitContainer.rect.width * canvas.scaleFactor
                   - rt.rect.width * canvas.scaleFactor * (1 - rt.pivot.x);

            // 最小y坐标 = 容器当前y坐标 - 容器轴心距离底边的距离 + UI轴心距离底边的距离
            minY = limitContainer.position.y
                   - limitContainer.pivot.y * limitContainer.rect.height * canvas.scaleFactor
                   + rt.rect.height * canvas.scaleFactor * rt.pivot.y;

            // 最大y坐标 = 容器当前x坐标 + 容器轴心距离顶边的距离 - UI轴心距离顶边的距离
            maxY = limitContainer.position.y
                   + (1 - limitContainer.pivot.y) * limitContainer.rect.height * canvas.scaleFactor
                   - rt.rect.height * canvas.scaleFactor * (1 - rt.pivot.y);
        }

        // 限制坐标范围
        Vector3 DragRangeLimit(Vector3 pos)
        {
            pos.x = Mathf.Clamp(pos.x, minX, maxX);
            pos.y = Mathf.Clamp(pos.y, minY, maxY);
            return pos;
        }

       
    }
}

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

v5bEezpf7PPs