首页 > 其他分享 >Unity用鼠标拖拽UI,UI跟随鼠标移动

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

时间:2023-05-26 14:34:28浏览次数:37  
标签:rt canvas 鼠标 距离 Unity limitContainer eventData UI scaleFactor

@TOC


效果

先上效果

Unity用鼠标拖拽UI,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;
        }

       
    }
}

标签:rt,canvas,鼠标,距离,Unity,limitContainer,eventData,UI,scaleFactor
From: https://blog.51cto.com/u_16023649/6355408

相关文章

  • YonBuilder低代码平台概论和基本使用
    一、引言1.代码平台的概念和发展历程低代码平台是一种通过可视化界面和模板化组件快速创建应用程序的平台,其发展历程主要经历了三个阶段:第一个阶段是第一代低代码平台:其主要关注业务流程管理及应用程序的速度开发,但其可扩展性和可定制性较低。第二个阶段是第二代低代码平台:充分注重......
  • U.S. hires lawyer for Google/Yahoo inquiry
    NEWYORK(Reuters)-TheU.S.JusticeDepartmenthashiredSandyLitvack,whowasitsformerantitrustchiefandWaltDisneyCo's(DIS.N:Quote,Profile,Research,StockBuzz)formervicechairman,toconsultonitsprobeofGoogleInc's(GOOG.O......
  • 帆软finebi、瓴羊Quick BI等为代表的国产BI工具崛起
    近年来,中美贸易摩擦的不断升级,使得国内企业受到“特殊照顾”。国家为了减少对外依赖,加快自主创新的步伐,逐渐加大对国产产品的支持力度。在这种情况下,国产BI工具逐渐替代外国BI工具成为了企业数据分析的新选择。瓴羊QuickBI、帆软finebi等国产BI工具在数据可视化等能力方面表现不输......
  • FLEX实践—动态控制MenuItem是否可用
    设计思路:利用<mx:menuitem></mx:menuitem>中的enabled属性控制指定的菜单项是否可用。由于需要动态设置,因此设置对应的全局变量与该属性进行绑定(即添加[Bindable]标签) 代码:<?xmlversion="1.0"encoding="utf-8"?><mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"......
  • 进口一定比国产香?横向对比tableau与瓴羊Quick BI
    随着国内企业数字化管理的不断提升,越来越多的企业开始引入BI工具。现在市面上的BI工具种类繁多,让企业在进行选型时感到“幸福的烦恼”——应该选择哪种BI工具?是选择国外的还是国产的?哪一种更适合中国企业?今天,我们将以国外和国产BI工具中的代表:Tableau和瓴羊QuickBI为例,详细比较两......
  • SpringBoot集成swagger-ui以及swagger分组显示
    文章目录1.swagger配置类2.使用swagger3.额外的学习经历大家好,这篇文章展示下如何在springboot项目中集成swagger-ui。有人说,这都是老生常谈,网上的例子数不胜数。确实swagger诞生至今已经很久了,但是在使用过程中我遇到一个问题,下面给大家分享下我的使用心得吧。1.swagger配置类第......
  • 使用resource读取properties文件,出现Cause: java.sql.SQLException: No suitable driv
    ###Errorqueryingdatabase.Cause:java.sql.SQLException:Nosuitabledriverfoundforhttp://maven.apache.org###Theerrormayexistincom/louis/dao/UserMapper.xml###Theerrormayinvolvecom.louis.dao.UserMapper.getUserList###Theerroroccurred......
  • 失传的museui控件组件属性
    提示框顶部导航条自动补全输入徽章底部导航组件按钮时间输入框数据表格对话框分割线表单栅格布局图标布局列表加载加载控件message弹框加载进度条选择框选择控件选项卡文本输入框消息提示提示1提示框  2顶部导航条  3......
  • el-button 鼠标移开后不自动失去焦点问题
    在按钮点击后强制按钮失去焦点1.在按钮点击的方法后加上失去焦点的方法<el-button@click="showDetail(scope.row,$event)">详情</el-button>showDetail(rowData,event){if(event.target.nodeName==='SPAN'){event.target.parentNode.blur()......
  • Unity2018.2 Standard Assets汉化
    下载中文汉化包拷贝到安装盘:\ProgramFiles\Unity\Editor\Data\Localization下面2018.1+的StandardAssets安装方法“自从我升级到2018.2之后,就再也找不到Unity自带的那些标准资源了,就是那个StandardAssets,里面有好多东西是我的必备资源呢,比如地形的那些贴图,第一人称控制......