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

Unity3D UI 拖拽

Unity3D 实现 UI 元素拖拽功能。

UI 拖拽

通常画布上的 UI 元素都是固定位置的,我们可以通过实现拖拽接口,让 UI 元素可以被拖拽到其他位置。

拖拽接口

创建一个脚本 UIDrag.cs,在默认继承的 MonoBehaviour 后面,再继承三个接口。

  • IBeginDragHandler(开始拖拽)
  • IDragHandler(拖拽中)
  • IEndDragHandler(结束拖拽)

继承接口之后,要在脚本中实现接口中定义的方法,即 OnBeginDragOnDragOnEndDrag

using UnityEngine;
using UnityEngine.EventSystems;public class UIDrag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{public void OnBeginDrag(PointerEventData eventData){}public void OnDrag(PointerEventData eventData){transform.position = eventData.position;}public void OnEndDrag(PointerEventData eventData){}
}

这里先在 OnDrag 方法中,把 eventData.position 赋值给 transform.position

然后创建一个 Image,把 UIDrag 脚本拖拽到 Image 上。

挂载组件

运行游戏,点击拖拽图片。

拖拽效果

画布渲染模式

上述的拖拽实现,是基于画布的 Overlay 模式。

Overlay模式

如果把画布渲染模式改成 Camera 模式,上述的代码实现就会出现问题。

因为 Camera 模式的画布会被缩小到相机的视野范围内,坐标的数值会变得很小。

Camera模式

此时的运行效果,拖拽后图片飞到了离画布很远的位置,坐标错误。

坐标错误

所以我们需要对拖拽时获得的坐标位置进行转换。

坐标转换

首先,定义一个 RectTransform 变量,在 Awake 时进行赋值。

然后利用 RectTransformUtility.ScreenPointToWorldPointInRectangle 方法,把自身的 recteventData.positioneventData.pressEventCamera 传入,如果坐标转换正常,则会返回转换后的 worldPoint,把这个坐标赋值给 rect.position 就可以了。

这个方法可以把屏幕空间坐标转换成 UI 元素所在的世界坐标。

using UnityEngine;
using UnityEngine.EventSystems;public class UIDrag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{RectTransform rect;void Awake(){rect = GetComponent<RectTransform>();}public void OnBeginDrag(PointerEventData eventData){}public void OnDrag(PointerEventData eventData){if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rect, eventData.position,eventData.pressEventCamera, out Vector3 worldPoint)){rect.position = worldPoint;}}public void OnEndDrag(PointerEventData eventData){}
}

修改代码后,无论画布是 Overlay 还是 Camera 模式,都可以正常拖拽。

切换模式

开始与结束拖拽

单纯的拖拽,只需要 OnDrag 方法,而 OnBeginDragOnEndDrag 可以为拖拽操作添加更多的逻辑处理。

例如,在场景中添加两个 Image,修改名字,改变颜色和不透明度,放置到左右两边。

添加容器

然后在代码中添加更多的逻辑,添加一个 raycastResults 用于保存射线检测到的 UI 元素列表,通过 EventSystem.current.RaycastAll 方法,把鼠标经过的 UI 元素都添加到列表中(包含 Image 自己)。

如果鼠标经过的 UI 元素的名字包含 Container,就把目标元素赋值给 target;如果列表中只有 Image 自己,则 target 为空。

我们可以在 OnBeginDrag 中,把 Image 原来的位置保存起来。在 OnEndDrag 中,检查 target 为空时,把原来的位置赋值给 Image,回到原位。只有在 target 不为空时,Image 才会移动到目标容器位置。

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;public class UIDrag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{RectTransform rect;List<RaycastResult> raycastResults;GameObject target;Vector3 originPos;void Awake(){rect = GetComponent<RectTransform>();raycastResults = new List<RaycastResult>();}public void OnBeginDrag(PointerEventData eventData){originPos = transform.position;}public void OnDrag(PointerEventData eventData){if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rect, eventData.position,eventData.pressEventCamera, out Vector3 worldPoint)){rect.position = worldPoint;}// 清空上一次的射线检测结果raycastResults.Clear();// 进行射线检测EventSystem.current.RaycastAll(eventData, raycastResults);// 包含两个 UI 元素以上if (raycastResults.Count > 1){// 遍历检测结果foreach (RaycastResult result in raycastResults){// 跳过自身对象的检测if (result.gameObject == gameObject) continue;// 检测到目标容器if (result.gameObject.name.Contains("Container")){target = result.gameObject;}}}// 只包含自己,没有目标else{target = null;}}public void OnEndDrag(PointerEventData eventData){if (target == null){transform.position = originPos;}else{transform.position = target.transform.position;}}
}

运行效果:

拖到容器

相关文章:

Unity3D UI 拖拽

Unity3D 实现 UI 元素拖拽功能。 UI 拖拽 通常画布上的 UI 元素都是固定位置的&#xff0c;我们可以通过实现拖拽接口&#xff0c;让 UI 元素可以被拖拽到其他位置。 拖拽接口 创建一个脚本 UIDrag.cs&#xff0c;在默认继承的 MonoBehaviour 后面&#xff0c;再继承三个接…...

介绍一下memcpy(c基础)

memcpy函数void *memcpy(void *dest, const void *src, size_t n); dest&#xff1a;指向目标内存区域的指针&#xff0c;即复制的目的地。src&#xff1a;指向源内存区域的指针&#xff0c;即要被复制的内容的来源。n&#xff1a;要复制的字节数 主要功能是将src所指向的内存…...

【网络面试篇】HTTP(2)(笔记)——http、https、http1.1、http2.0

目录 一、相关面试题 1. HTTP 与 HTTPS 有哪些区别&#xff1f; 2. HTTPS 的工作原理&#xff1f;&#xff08;https 是怎么建立连接的&#xff09; &#xff08;1&#xff09;ClientHello &#xff08;2&#xff09;SeverHello &#xff08;3&#xff09;客户端回应 &a…...

python-23-一篇文章帮你理解Python推导式

python-23-一篇文章帮你理解Python推导式 一.简介 在 Python 中&#xff0c;推导式&#xff08;Comprehensions&#xff09;是一个简洁的语法&#xff0c;用于通过某种可迭代对象快速生成新的对象&#xff08;如列表、字典、集合等&#xff01;来开始我们今天的日拱一卒&…...

WPF中如何简单的使用CommunityToolkit.Mvvm创建一个项目并进行 增删改查

目录 开始前准备的数据库dbblog如下&#xff1a; 第一步&#xff1a;创建项目后下载四个NuGet程序包 第二步&#xff1a;删除原本的MainWindow.XAML文件 并创建如下的目录结构 然后在View文件夹下面创建Login.XAML和Main.XAML 并且在App.XAML中将启动项改为Login.X…...

CesiumJS 案例 P15:检测标记、鼠标点击移动标记、鼠标拖动标记

CesiumJS CesiumJS API&#xff1a;https://cesium.com/learn/cesiumjs/ref-doc/index.html CesiumJS 是一个开源的 JavaScript 库&#xff0c;它用于在网页中创建和控制 3D 地球仪&#xff08;地图&#xff09; 一、检测标记 <!DOCTYPE html> <html lang"en&…...

Webserver(4.9)本地套接字的通信

目录 本地套接字 本地套接字 TCP\UDP实现不同主机、网络通信 本地套接字实现本地的进程间的通信&#xff0c;类似的&#xff0c;一般采用TCP的通信流程 生成套接字文件 #include<arpa/inet.h> #include<stdio.h> #include<stdlib.h> #include<unistd.h&…...

[IAA系列] Image Aesthetic Assessment

Preface 本文旨在记录个人结合AI工具对IAA这个领域的一些了解&#xff0c;主要是通过论文阅读的方式加深对领域的了解。有什么问题&#xff0c;欢迎在评论区提出并讨论。 什么是IAA Image Aesthetic Assessment&#xff08;图像美学评估&#xff09;是一种评估图像在视觉上的…...

基于springboot的高校科研管理系统(源码+调试+LW)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据你想解决的问题&#xff0c;今天给…...

Flutter环境配置

配置环境变量 PUB_HOSTED_URLhttps://pub.flutter-io.cn FLUTTER_STORAGE_BASE_URLhttps://storage.flutter-io.cn 这个命令是用来配置 Flutter 的镜像源地址&#xff0c;主要是为了解决在中国大陆地区访问 Flutter 官方资源较慢的问题 具体的操作做如下: 右键点击"此…...

Rip动态路由及Rip动态路由优化

动态路由Rip Tip&#xff1a;Rip动态路由实现多个路由间不同网段通信。 本次实验目的&#xff0c;通过给ar1,ar2,ar3配置rip动态路由&#xff0c;实现pc1 ping通 pc2。 AR1配置如下&#xff1a; <Huawei>sy Enter system view, return user view with CtrlZ. [Huawei]…...

双路快速排序和三路排序算法

双路快速排序 一、概念及其介绍 双路快速排序算法是随机化快速排序的改进版本&#xff0c;partition 过程使用两个索引值&#xff08;i、j&#xff09;用来遍历数组&#xff0c;将 <v 的元素放在索引i所指向位置的左边&#xff0c;而将 >v 的元素放在索引j所指向位置的…...

SQL server增删改查语句和实例

在 SQL Server 中&#xff0c;增删改查操作分别对应 INSERT、DELETE、UPDATE 和 SELECT 语句。以下是具体介绍及实例&#xff1a; 一、插入数据&#xff08;INSERT&#xff09; 语法&#xff1a; INSERT INTO table_name (column1, column2, column3,...) VALUES (value1, val…...

强化学习_06_pytorch-PPO2实践(ALE/Breakout-v5)

一、环境适当调整 数据收集&#xff1a;RecordEpisodeStatistics进行起始跳过n帧&#xff1a;baseSkipFrame一条生命结束记录为done:EpisodicLifeEnv得分处理成0或1:ClipRewardEnv叠帧: FrameStack 图像环境的基本操作&#xff0c;方便CNN捕捉智能体的行动 向量空间reset处理修…...

《JVM第8课》垃圾回收算法

文章目录 1.标记算法1.1 引用计数法1.2 可达性分析法 2.回收算法2.1 标记-清除算法&#xff08;Mark-Sweep&#xff09;2.2 复制算法&#xff08;Coping&#xff09;2.3 标记-整理算法&#xff08;Mark-Compact&#xff09; 3.三种垃圾回收算法的对比 为什么要进行垃圾回收&…...

SpringBoot整合Freemarker(二)

if分支 语法&#xff1a; <#if condition>... <#elseif condition2>... <#elseif condition3>... <#else>... </#if> 例子&#xff1a; <#if x 1>x is 1 </#if> --------------------------------- <#if x 1>x is 1 <…...

element plus el-form自定义验证输入框为纯数字函数

element plus 的el-form 使用自定义验证器&#xff0c;验证纯数字&#xff0c;禁止输入小数、中文、字母、特殊符号。input的maxlength为最大输入多少位长度 效果图 <el-form ref"dataFormRef" :model"dataForm" :rules"dataRules" label-w…...

Android笔记(三十一):Deeplink失效问题

背景 通过deeplink启动应用之后&#xff0c;没关闭应用的情况下&#xff0c;再次使用deeplink会失效的问题&#xff0c;是系统bug导致的。此bug仅在某些设备&#xff08;Nexus 5X&#xff09;上重现&#xff0c;launchMode并且仅当应用程序最初通过深层链接启动并再次通过深层…...

图神经网络初步实验

实验复现来源 https://zhuanlan.zhihu.com/p/603486955 该文章主要解决问题&#xff1a; 1.加深对图神经网络数据集的理解 2.加深对图神经网络模型中喂数据中维度变化的理解 原理问题在另一篇文章分析&#xff1a; 介绍数据集&#xff1a;cora数据集 其中的主要内容表示为…...

创建线程时传递参数给线程

在C中&#xff0c;可以使用 std::thread 来创建和管理线程&#xff0c;同时可以通过几种方式将参数传递给线程函数。这些方法包括使用值传递、引用传递和指针传递。下面将对这些方法进行详细讲解并给出相应的代码示例。 1. 值传递参数 当你创建线程并希望传递参数时&#xff…...

兴业严选|美国总统都是不良资产出身 法拍市场是否将大众化

北京时间11月6日&#xff0c;特朗普赢得美国大选。 说起特朗普那就不得不提他的发家史&#xff0c;那可真是一笔笔不良资产投资堆出来的。 没错&#xff0c;特朗普就是处理不良资产的高手&#xff0c;战果丰硕。 改造斯威夫特小镇、 康莫德酒店、打造特朗普&#xff08;TRUM…...

C#-拓展方法

概念&#xff1a;为现有的非静态变量类型&#xff0c;添加方法 语法&#xff1a; 访问修饰符 static 返回值 函数名(this 拓展类名 参数名, 参数类型 参数名,参数类型 参数名....){} 而public static void F(this Console()){ }是错的。Console是静态类不可以为静态类添加方…...

加锁失效,非锁之过,加之错也|京东零售供应链库存研发实践

本文导读 从事京东零售供应链库存业务&#xff0c;库存数量操作增减十分频繁&#xff0c;并且项目开发中会常常遇到各种并发情况&#xff0c;一旦库存数量操作有误&#xff0c;势必给前台销售产生损失影响&#xff0c;因此需要关注对库存数量并发操作下的一致性问题。 大部分…...

vue3 传值的几种方式

一.父组件传子组件 父组件 //父组件 <Decisionobject :Decisionselected"Decisionselected"></Decisionobject> <script lang"ts" setup> let Decisionselected ref(false); </script>子组件 <script lang"ts" s…...

AUTOSAR CP NVRAM Manager规范导读

一、NVRAM Manager功能概述 NVRAM Manager是AUTOSAR(AUTomotive Open System ARchitecture)框架中的一个模块,负责管理非易失性随机访问存储器(NVRAM)。它提供了一组服务和API,用于在汽车环境中存储、维护和恢复NV数据。以下是NVRAM Manager的一些关键功能: 数据存储和…...

2024阿里云CTF Web writeup

《Java代码审计》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484219&idx1&sn73564e316a4c9794019f15dd6b3ba9f6&chksmc0e47a67f793f371e9f6a4fbc06e7929cb1480b7320fae34c32563307df3a28aca49d1a4addd&scene21#wechat_redirect 前言 又是周末…...

软件著作权申请教程(超详细)(2024新版)软著申请

目录 一、注册账号与实名登记 二、材料准备 三、申请步骤 1.办理身份 2.软件申请信息 3.软件开发信息 4.软件功能与特点 5.填报完成 一、注册账号与实名登记 首先我们需要在官网里面注册一个账号&#xff0c;并且完成实名认证&#xff0c;一般是注册【个人】的身份。中…...

三维测量与建模笔记 - 3.2 直接线性变换法标定DLT

DLT - Direct Linear Transform 上图中&#xff0c;透视成像对应的公式是共线方程&#xff0c;可以参考以下链接&#xff1a; https://zhuanlan.zhihu.com/p/101549821https://zhuanlan.zhihu.com/p/101549821 对于标定来说&#xff0c;需要找到。已知量是。 (u,v)是…...

Whisper AI视频(音频)转文本

在信息化时代&#xff0c;如何高效处理丰富的音频和视频内容成为了一个重要课题。将这些内容转化为文本不仅能提高信息的可获取性&#xff0c;还能促进更广泛的传播。Whisper Desktop作为一款先进的语音识别工具&#xff0c;能够帮助用户轻松实现音频和视频的转文本功能。 什么…...

全网最详细RabbitMQ教学包括如何安装环境【RabbitMQ】RabbitMQ + Spring Boot集成零基础入门(基础篇)

目录 一、初始Rabbitmq1、什么是Rabbitmq&#xff0c;它的概述是什么&#xff1f;2、RabbitMQ的应用场景3、RabbitMQ主要组件4、RabbitMQ 的优点5、与其他消息队列性能比较 二、RabbitMQ环境安装初始化三、SpringAMQPRabbitMQ实战入门&#xff08;基本API&#xff09;1、实战入…...