当前位置: 首页 > 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…...

4种颠覆性组合:重构Pixelle-Video的模块化潜能

4种颠覆性组合&#xff1a;重构Pixelle-Video的模块化潜能 【免费下载链接】Pixelle-Video &#x1f680; AI 全自动短视频引擎 | AI Fully Automated Short Video Engine 项目地址: https://gitcode.com/GitHub_Trending/pi/Pixelle-Video 想象一下&#xff1a;输入&qu…...

OriginPro 2023 相关性热图插件 CorrelationPlot 保姆级安装与配置指南(附资源下载)

OriginPro 2023 CorrelationPlot插件全流程配置指南&#xff1a;从零基础到高效科研可视化 科研数据处理中&#xff0c;相关性热图&#xff08;Correlation Plot&#xff09;是揭示变量间关联强度的利器。对于非编程背景的研究者而言&#xff0c;OriginPro的CorrelationPlot插件…...

中小企业老板必看:收藏这份AI转型轻装上阵指南,领跑AI浪潮!

文章指出&#xff0c;在AI浪潮下&#xff0c;中小企业并非处于劣势。通过“轻装上阵”策略&#xff0c;摆脱历史包袱&#xff0c;利用流程未固化、决策链短等优势&#xff0c;中小企业可以弯道超车。文章提出了五个AI转型方法论&#xff1a;1&#xff09;轻装上阵&#xff0c;利…...

taotoken用量看板如何帮助项目管理者精细化追踪api成本

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 taotoken用量看板如何帮助项目管理者精细化追踪api成本 对于依赖大模型API进行开发的项目团队而言&#xff0c;成本控制始终是一个…...

CANN/asnumpy-docs 架构设计

Architecture 【免费下载链接】asnumpy-docs 项目地址: https://gitcode.com/cann/asnumpy-docs This document describes the internal architecture of AsNumpy, including the three-layer design, the core NPUArray data structure, the API module layout, and t…...

别再折腾了!Windows 11下TeX Live 2024 + VS Code配置LaTeX环境保姆级教程

别再折腾了&#xff01;Windows 11下TeX Live 2024 VS Code配置LaTeX环境保姆级教程 对于科研人员和学术写作者来说&#xff0c;LaTeX始终是专业排版的不二之选。但传统LaTeX编辑器如TeXstudio虽然功能全面&#xff0c;却难以融入现代开发者的工作流。本文将带你用VS Code搭建…...

论文降重与改写:2026 最新降AI率平台测评与推荐

2026年真正好用的AI论文降重与改写工具&#xff0c;核心看降重效果、去AI味、格式保留、学术适配四大指标。综合实测&#xff0c;千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队&#xff0c;覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 …...

深入解析Keil MDK编译流程:从C代码到单片机运行的完整过程

1. 项目概述&#xff1a;从源码到芯片运行的旅程作为一名在嵌入式领域摸爬滚打了十多年的老工程师&#xff0c;我经常被问到这样一个问题&#xff1a;“我写的C代码&#xff0c;点一下MDK的‘Build’按钮&#xff0c;怎么就变成能在单片机里跑的程序了&#xff1f;” 这背后&am…...

别再死记硬背了!用Python脚本模拟UDS 28服务,5分钟搞懂通信控制

用Python实战模拟UDS 28服务&#xff1a;5分钟掌握CAN总线通信控制 在汽车电子开发与测试中&#xff0c;UDS诊断协议的理解往往停留在理论层面&#xff0c;而实际动手操作才是掌握精髓的关键。28服务作为ISO14229-1标准中的通信控制核心&#xff0c;直接影响ECU的报文收发行为。…...

手把手教你用Simulink搭建带Resolver的永磁同步电机FOC仿真模型(从电机库到代码生成)

从零构建永磁同步电机FOC仿真&#xff1a;集成旋变解码与代码生成的完整实践指南 在电机控制领域&#xff0c;快速验证算法并实现从仿真到硬件的无缝过渡是工程师面临的核心挑战。本文将带您完成一个包含旋转变压器&#xff08;Resolver&#xff09;信号处理的完整永磁同步电机…...