当前位置: 首页 > news >正文

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生命周期总结 生命周期主要分为以下几个阶段&#xff1a; Mounting:创建虚拟DOM&#xff0c;渲染UI(初始化)Updating&#xff1a;更新虚拟DOM&#xff0c;重新渲染UI&#xff1b;(更新)UnMounting&#xff1a;删除虚拟DOM&#xff0c;移除UI&#xff1b;(销毁) 生命周期…...

初探推荐系统-01

文章目录一、什么是推荐系统是什么为什么长尾理论怎么做二、相似度算法杰卡德相似系数余弦相似度三、基于内容的推荐算法如何获取到用户喜欢的物品如何确定物品的特征四、推荐算法实验方法评测指标推荐效果实验方法1、离线实验2、用户调查3、在线实验评测指标1、预测准确度评分…...

html实现浪漫的爱情日记(附源码)

文章目录1.设计来源1.1 主界面1.2 遇见1.3 相熟1.4 相知1.5 相念2.效果和源码2.1 动态效果2.2 源代码2.3 代码结构源码下载更多爱情表白源码作者&#xff1a;xcLeigh 文章地址&#xff1a;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作为灵活且强大的异步执行框架&#xff0c;其支持多种不同类型的任务执行策略&#xff0c;提供了一种标准的方法将任务的提交过程和执行过程解耦开发&#xff0c;基于生产者-消费者模式&#xff0c;其提交任务的线程相当于生…...

Java 常用 API

文章目录一、Math二、System三、Object1. toString() 方法2. equals() 方法四、Arrays1. 冒泡排序2. Arrays 常用方法五、基本类型包装类1. Integer2. int 和 String 相互转换3. 字符串中数据排序4. 自动装箱和拆箱六、日期类1. Date2. SimpleDateFormat3. Calendar4. 二月天一…...

记一次分布式环境下TOKEN实现用户登录

背景&#xff1a; ​ 以前的单体项目&#xff0c;使用的是session来保存用户登录状态&#xff0c;控制用户的登录过期时间等信息&#xff0c;但是这个session是只保存在该服务器的这个系统内存中。系统只有一个服务就没关系&#xff0c;但是如果是分布式的服务&#xff0c;每个…...

用cpolar发布本地的论坛网站 1

网页论坛向来是个很神奇的地方&#xff0c;曾经的天涯论坛和各种BBS&#xff0c;大家聚在在一起讨论某个问题&#xff0c;也能通过论坛发布想法&#xff0c;各种思维碰撞在一起&#xff0c;发生很多有趣的故事&#xff0c;也产生了很多流传一时的流行语录。当然&#xff0c;如果…...

CSS的4种引入方式

CSS的4种引入方式 目录CSS的4种引入方式一、内嵌式&#xff1a;CSS写在style标签中二、外联式&#xff1a;CSS写在一个单独的.css文件中三、行内式&#xff1a;CSS写在标签的style属性中四、导入外部样式五、css引用的优先级六、link和import的区别一、内嵌式&#xff1a;CSS写…...

Shell高级——Linux中的文件描述符(本质是数组的下标)

以下内容源于C语言中文网的学习与整理&#xff0c;非原创&#xff0c;如有侵权请告知删除。 前言 Linux中一切接文件&#xff0c;比如 C 源文件、视频文件、Shell脚本、可执行文件等&#xff0c;就连键盘、显示器、鼠标等硬件设备也都是文件。 一个 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推流配置方法一&#xff1a;ngnix&#xff08;不推荐&#xff0c;推流不好使&#xff09;方法二&#xff1a;srs&#xff08;强烈推荐&#xff09;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 题目详细&#xff1a;LeetCode.216 做过上一题组合后&#xff0c;再来写这道题就显得得心应手了&#xff0c;通过理解回溯算法的模版&#xff0c;也总结出了算法中的一些特点&#xff1a; 回溯算法与递归算法类似&#xff0c;同样需要参数、结束条件和主体逻辑回…...

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功能“上新”

日前&#xff0c;中电金信源启移动开发平台MADP功能迭代升级&#xff0c;“上新”源启小程序开发平台。定位“为金融业定制”的移动PaaS平台&#xff0c;源启小程序开发平台为银行、互联网金融、保险、证券客户提供一站式小程序的开发、运营、营销全生命周期管理技术支撑&#…...

Kubernetes06:Controller (Deployment无状态应用)

Kubernetes06:Controller 1、什么是controller 管理和运行容器的对象&#xff0c;是一个物理概念 在集群上管理和运行容器的对象 2、Pod和Controller之间的关系 Pod是通过controller来实现应用的运维 比如伸缩、滚动升级等等操作Pod和Controller之间通过 label 标签建立关系…...

低代码开发平台选型必看指南

低代码开发是近年来逐渐兴起的一种新型软件开发方式。它通过封装常见的软件开发流程和代码&#xff0c;使得非专业的开发者也能够轻松创建复杂的应用程序。这种开发方式已经受到了许多企业的青睐&#xff0c;成为提高生产效率、降低开发成本的一种有效途径。 低代码开发的核心…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...