Unity UGUI 拖拽组件
效果展示
使用方式
拖到图片上即可用
父节点会约束它的活动范围哦~
父节点会约束它的活动范围哦~
父节点会约束它的活动范围哦~
源码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;/// <summary>
/// UI DragComponent
///
/// Easy ui drag and drop
///
/// Easy~~~
///
/// @anchor ChenJC
/// @time: 2023/02/28
/// </summary>
public class DragComponent : MonoBehaviour, IBeginDragHandler, IDragHandler, IDropHandler
{RectTransform rectTransform, parentRectTrans;float minX, minY, maxX, maxY;Vector2 offset;public delegate void DragHandlerEvent( Vector2 currentPos );public DragHandlerEvent dragBeginEvent;public DragHandlerEvent dragEvent;public DragHandlerEvent dropEvent;#region Monobehavior Methodsprivate void Awake(){parentRectTrans = transform.parent as RectTransform;rectTransform = transform as RectTransform;}private void Start(){var parentAnchorX = parentRectTrans.pivot.x * parentRectTrans.rect.width;var parentAnchorY = parentRectTrans.pivot.y * parentRectTrans.rect.height;minX = rectTransform.rect.width * 0.5f - parentAnchorX;minY = rectTransform.rect.height * 0.5f - parentAnchorY;maxX = parentRectTrans.rect.width - rectTransform.rect.width * 0.5f - parentAnchorX;maxY = parentRectTrans.rect.height - rectTransform.rect.height * 0.5f - parentAnchorY;}#endregion#region Internal Methodsprivate Vector2 ConstraintWithinParentNode( Vector2 pos ){pos.x = Mathf.Clamp( pos.x, minX, maxX );pos.y = Mathf.Clamp( pos.y, minY, maxY );return pos;}private bool Convert2local( Vector2 screenPos, out Vector2 localPos, Camera camera ){return RectTransformUtility.ScreenPointToLocalPointInRectangle( parentRectTrans, screenPos, camera, out localPos );}#endregion#region Drag Handler Methodspublic void OnBeginDrag( PointerEventData eventData ){Vector2 localPos;if ( Convert2local( eventData.position, out localPos, eventData.pressEventCamera ) ){Vector2 src = rectTransform.localPosition;offset = src - localPos;dragBeginEvent?.Invoke( src );}}public void OnDrag( PointerEventData eventData ){Vector2 localPos;if ( Convert2local( eventData.position, out localPos, eventData.pressEventCamera ) ){Vector2 dest = ConstraintWithinParentNode( localPos + offset );rectTransform.localPosition = dest;dragEvent?.Invoke( dest );}}public void OnDrop( PointerEventData eventData ){Vector2 localPos;if ( Convert2local( eventData.position, out localPos, eventData.pressEventCamera ) ){Vector2 dest = ConstraintWithinParentNode( localPos + offset );rectTransform.localPosition = dest;dropEvent?.Invoke( dest );}}#endregion
}
拖拽事件监听
依次 开始拖拽时触发; 拖拽过程中持续触发; 拖拽结束时触发
原理介绍
开始拖拽的时候
offset = sub.localtionPos - p.localtionPos
通过计算鼠标点 计算出 相对于图片原点的 偏移 并缓存
public void OnBeginDrag( PointerEventData eventData ){Vector2 localPos;if ( Convert2local( eventData.position, out localPos, eventData.pressEventCamera ) ){Vector2 src = rectTransform.localPosition;offset = src - localPos;dragBeginEvent?.Invoke( src );}}
拖拽过程中 我们加上这个偏移向量 就能得到相对偏移的拖拽方式
sub.locationsPos = p.locationPos + offset
public void OnDrag( PointerEventData eventData ){Vector2 localPos;if ( Convert2local( eventData.position, out localPos, eventData.pressEventCamera ) ){Vector2 dest = ConstraintWithinParentNode( localPos + offset );rectTransform.localPosition = dest;dragEvent?.Invoke( dest );}}
限制活动范围 保持在父节点以内活动
示意图
如图可以知道 最小X 等于自身宽 的一半 同时要减去父节点 宽的一半
可以知道 最小Y 等于自身高 的一半 同时要减去父节点 高的一半
最大值 是父节点一半 - 自身大小的一半 在Unity里 你可以通过 pivot 来获取 图片锚点相对于图片自身size的百分比值 ( 0~1)
计算出最小X,最小Y,最大X,最大Y
private void Start(){var parentAnchorX = parentRectTrans.pivot.x * parentRectTrans.rect.width;var parentAnchorY = parentRectTrans.pivot.y * parentRectTrans.rect.height;minX = rectTransform.rect.width * 0.5f - parentAnchorX;minY = rectTransform.rect.height * 0.5f - parentAnchorY;maxX = parentRectTrans.rect.width - rectTransform.rect.width * 0.5f - parentAnchorX;maxY = parentRectTrans.rect.height - rectTransform.rect.height * 0.5f - parentAnchorY;}
新的位置约束在范围内
private Vector2 ConstraintWithinParentNode( Vector2 pos ){pos.x = Mathf.Clamp( pos.x, minX, maxX );pos.y = Mathf.Clamp( pos.y, minY, maxY );return pos;}
相关文章:
Unity UGUI 拖拽组件
效果展示 使用方式 拖到图片上即可用 父节点会约束它的活动范围哦~ 父节点会约束它的活动范围哦~ 父节点会约束它的活动范围哦~ 源码 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems;/// <summary> /…...
面试总结——react生命周期
react生命周期总结 生命周期主要分为以下几个阶段: Mounting:创建虚拟DOM,渲染UI(初始化)Updating:更新虚拟DOM,重新渲染UI;(更新)UnMounting:删除虚拟DOM,移除UI;(销毁) 生命周期…...
初探推荐系统-01
文章目录一、什么是推荐系统是什么为什么长尾理论怎么做二、相似度算法杰卡德相似系数余弦相似度三、基于内容的推荐算法如何获取到用户喜欢的物品如何确定物品的特征四、推荐算法实验方法评测指标推荐效果实验方法1、离线实验2、用户调查3、在线实验评测指标1、预测准确度评分…...
html实现浪漫的爱情日记(附源码)
文章目录1.设计来源1.1 主界面1.2 遇见1.3 相熟1.4 相知1.5 相念2.效果和源码2.1 动态效果2.2 源代码2.3 代码结构源码下载更多爱情表白源码作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/129264757 html实现浪漫的爱情…...
detectron2容器环境安装问题(1)
1为避免后面出现需求python版本低于3.7的情况ERROR: Package detectron2 requires a different Python: 3.6.9 not in >3.7可以第一步就使用 nvidia/cuda:11.1.1-cudnn8-devel-ubuntu20.04镜像2如果使用了18.04的镜像nvidia/cuda:11.1.1-cudnn8-devel-ubuntu18.04可以使用我…...
JAVA线程池原理详解二
JAVA线程池原理详解二 一. Executor框架 Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生…...
Java 常用 API
文章目录一、Math二、System三、Object1. toString() 方法2. equals() 方法四、Arrays1. 冒泡排序2. Arrays 常用方法五、基本类型包装类1. Integer2. int 和 String 相互转换3. 字符串中数据排序4. 自动装箱和拆箱六、日期类1. Date2. SimpleDateFormat3. Calendar4. 二月天一…...
记一次分布式环境下TOKEN实现用户登录
背景: 以前的单体项目,使用的是session来保存用户登录状态,控制用户的登录过期时间等信息,但是这个session是只保存在该服务器的这个系统内存中。系统只有一个服务就没关系,但是如果是分布式的服务,每个…...
用cpolar发布本地的论坛网站 1
网页论坛向来是个很神奇的地方,曾经的天涯论坛和各种BBS,大家聚在在一起讨论某个问题,也能通过论坛发布想法,各种思维碰撞在一起,发生很多有趣的故事,也产生了很多流传一时的流行语录。当然,如果…...
CSS的4种引入方式
CSS的4种引入方式 目录CSS的4种引入方式一、内嵌式:CSS写在style标签中二、外联式:CSS写在一个单独的.css文件中三、行内式:CSS写在标签的style属性中四、导入外部样式五、css引用的优先级六、link和import的区别一、内嵌式:CSS写…...
Shell高级——Linux中的文件描述符(本质是数组的下标)
以下内容源于C语言中文网的学习与整理,非原创,如有侵权请告知删除。 前言 Linux中一切接文件,比如 C 源文件、视频文件、Shell脚本、可执行文件等,就连键盘、显示器、鼠标等硬件设备也都是文件。 一个 Linux 进程可以打开成百上…...
Nvidia jetson nano硬件架构
资料来源 官方文档中心 https://developer.nvidia.com/embedded/downloads -> 选jetson -> Jetson Nano Product Design Guide //产品设计指导(入口) //-> 1.1 References 列出了相关的文档 -> Jetson Nano Developer Kit Carrier Board Specification //板子标注…...
ffmpeg多路同时推流
一、ffmpeg常见使用方法1.1利用FFMPEG命令进行文件分割1.2转换格式1.3推流配置方法一:ngnix(不推荐,推流不好使)方法二:srs(强烈推荐)1.4查看nginx启动是否成功二、ffmpeg推流——>ngnix单路…...
一次性搞定 `SHOW SLAVE STATUS` 的解读
一次性搞定 SHOW SLAVE STATUS 的解读 解析日志文件的位置 诚然, GTID(全局事务标识符)已经在 MySQL 5.6中得到支持, 此外,还可以通过 Tungsten replicator 软件来实现(2009年以后一直有谷歌在维护,不是吗?)。 但有一部分人还在使用MySQL 5.5的标准副本方式, 那么这些二进制日…...
【代码随想录训练营】【Day25】第七章|回溯算法 |216.组合总和III|17.电话号码的字母组合
组合总和III 题目详细:LeetCode.216 做过上一题组合后,再来写这道题就显得得心应手了,通过理解回溯算法的模版,也总结出了算法中的一些特点: 回溯算法与递归算法类似,同样需要参数、结束条件和主体逻辑回…...
docker使用
https://blog.csdn.net/u012563853/article/details/125295985http://www.ppmy.cn/news/11249.html启动 docker服务并设置开机自动启动dockersudo systemctl start docker sudo systemctl enable dockerdocker 常见启动失败问题:https://blog.csdn.net/zhulianseu/article/deta…...
手把手docker registry配置登录名/密码
我们的Docker私有仓库Registry服务只有加了认证机制之后我们的Registry服务才会更加的安全可靠。赶快跟随以下步骤来增加认证机制吧。 创建docker registry工作目录 mkdir -p /data/docker.registry 创建将保存凭据的文件夹 mkdir -p /data/docker.registry/etc/registry/auth…...
一步打通多渠道服务场景 中电金信源启移动开发平台MADP功能“上新”
日前,中电金信源启移动开发平台MADP功能迭代升级,“上新”源启小程序开发平台。定位“为金融业定制”的移动PaaS平台,源启小程序开发平台为银行、互联网金融、保险、证券客户提供一站式小程序的开发、运营、营销全生命周期管理技术支撑&#…...
Kubernetes06:Controller (Deployment无状态应用)
Kubernetes06:Controller 1、什么是controller 管理和运行容器的对象,是一个物理概念 在集群上管理和运行容器的对象 2、Pod和Controller之间的关系 Pod是通过controller来实现应用的运维 比如伸缩、滚动升级等等操作Pod和Controller之间通过 label 标签建立关系…...
低代码开发平台选型必看指南
低代码开发是近年来逐渐兴起的一种新型软件开发方式。它通过封装常见的软件开发流程和代码,使得非专业的开发者也能够轻松创建复杂的应用程序。这种开发方式已经受到了许多企业的青睐,成为提高生产效率、降低开发成本的一种有效途径。 低代码开发的核心…...
OVN:ovn20.03.1/ovs2.13.0编译rpm过程
操作系统openeuler22.0,x86架构分别下载ovn和ovs的源码https://github.com/openvswitch/ovs/tree/v2.13.0https://github.com/ovn-org/ovn/tree/v20.03.1安装必要工具:yum install -y unzip tar make autoconf automake libtool rpm-build gcc libuuid-d…...
Shell管道
一、管道是什么 英文是pipe。 把一个命令的标准输出作为下一个命令的标准输入,以这种方式连接的两个或者多个命令就形成了管道 使用竖线|连接多个命令,称为管道符。 语法格式如下: command1 | command2 [ | commandN... ] command1的标准…...
Zynq UltraScale系列使用MIPI CSI-2 RX Subsystem 解码MIPI视频PD输出 提供2套工程源码和技术支持
目录1、前言2、设计思路和架构3、vivado工程详解4、上板调试验证5、福利:工程代码的获取1、前言 本设计采用OV5640摄像头MIPI模式作为输入,分辨率为1280x72060Hz,MIPI解码方案采用Xilinx官方提供的MIPI CSI-2 RX Subsystem IP解码MIPI视频&a…...
C++:详解C++11 线程休眠函数
休眠函数简介1: 让线程休眠一段时间1.1:std::chrono 的时钟 clock简介 C11 之前并未提供专门的休眠函数,C语言的 sleep、usleep函数其实是系统提供的函数,不同的系统函数的功能还要些差异。 在Windows系统中,sleep的参数是毫秒 …...
TryHackMe-The Great Escape(Docker)
The Great Escape 我们的开发人员创建了一个很棒的新网站。你能冲出沙盒吗? 端口扫描 循例 nmap Web信息收集 robots.txt: /exif-util是文件上传点,但是绕过之后貌似没啥用 在robots.txt当中披露了可能存在.bak.txt,现在我们已知的文件就是…...
这么强才给我28k,我头都不回,转身拿下40k~
时间真的过得很快,眨眼就从校园刚出来的帅气小伙变成了油腻大叔,给各位刚入道的测试朋友一点小建议,希望你们直通罗马吧! 如何选择自己合适的方向 关于选择测试管理: 第一,你一定不会是一个喜欢技术&…...
【Python学习笔记】第二十一节 Python Lambda 函数
Python 提供了非常多的库和内置函数。有不同的方法可以执行相同的任务,而在 Python 中,有个万能之王函数:lambda 函数,它以不同的方式在任何地方使用。一、Lambda 函数简介在 Python 中,函数可以接受一个或多个位置参数…...
Nginx学习整理
Nginx学习第一章 Nginx概述1.1、Nginx概述1.2、Nginx官网1.3、Nginx用处第二章 Nginx单实例安装2.1、环境说明2.2、安装依赖2.3、Nginx下载2.4、Nginx解压2.5、Nginx安装2.6、Nginx命令2.7、开放防火墙2.8、启动后效果第三章 Nginx正向代理、反向代理3.1、概述3.2、反向代理配置…...
阿里面试之Hr面,这个套路把我坑惨了......
作为技术类的测试工程师面试,往往要经过多次面试才能拿到心仪的offer,这里面有技术一面、二面…,甚至总监面等,还有一个必不可少的就是HR面,一般HR会出现在你面试的最前面和最后面,前面是了解你的基本情况&…...
域基础和基本环境搭建
1.1 名词解释 域和工作组的区别: 工作组中所有的计算机都是对等的,也就是没有服务器和客户机的之分,所以工作组并不存在真正的集中管理作用;域是一个有安全边界的计算机集合,安全边界指的是一个域中的用户无法访问到另…...
企业官方网站建设的作用/站长工具在线免费
1、在码云新建创库,并且选择初始化README.md以启用svn服务。 2、在该项目的管理界面,勾上 [启用SVN访问] 3、在项目首页找到SVN的仓库地址,复制 4.在本地新建一个文件夹,名称随意 5.右键SVN检出,粘贴刚刚复制的地址&a…...
做推文的网站的推荐/太原网站建设优化
序列分类的任务是为整个输入序列预测一个类别标签。在许多领域中,包括基因和金融领域,这样的问题都极为常见。NLP中的一个突出例子是情绪分析。使用国际电影数据库的影评数据集,该数据集的目标值是二元的---正面的和负面的。将逐个单词地查看…...
淘宝客怎么做网站导购/网络营销的现状分析
之前对Spring缓存的理解是每次设置缓存之后,重复请求会刷新缓存时间,但是问题排查阅读源码发现,跟自己的理解大相径庭。所有的你以为都仅仅是你以为!!!! 背景 目前项目使用的spring缓存&#…...
如何使用天翼云主机建设网站/世界杯数据分析
使用CentOS最新的安装镜像CentOS 7.3在测试环境安装了一台服务器,然后安装一堆软件。然后安装P软件时报错:找不到vxlan内核模块。 之前在CentOS 7.2上都安装好好的。要么重新安装服务器,要么给7.3降低到7.2的内核。查看当前内核版本ÿ…...
公司主营网站开发怎么做账/旺道seo营销软件
有 1000 个一模一样的瓶子,其中有 999 瓶是普通的水,有一瓶是毒药。任何喝下毒药的生物都会在一星期之后死亡。现在,你只有 10 只小白鼠和一星期的时间,如何检验出哪个瓶子里有毒药? 参考答案: 【1】根据2^…...
网站开发工程师证书有用吗/长尾关键词网站
【面试题56-Ⅱ 数组中数字出现的次数 II】 在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。 Leetcode题目对应位置: 面试题56-Ⅱ:数组中数字出现的次数 II 思路:使用位运算。…...