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

unity 模型显示在UI上 并交互(点击、旋转、缩放)

项目工程:unity模型显示在UI上并交互(点击、旋转、缩放)资源-CSDN文库

1.在Assets创建 Render Texture(下面会用到),根据需要设置Size

2.创建UIRawImage,并把Render Texture赋上

 3.创建相机,如下图:

4.基本UI的准备工作完成,剩下的就是代码了,值得一提:相机我不喜欢单独拿出去管理,就和UI一起就好。如图:

 5.相机控制,直接上代码(添加了一个判断,鼠标必须在rawImage上,其他UI上无效):

/**********************************************************************文件信息文件名(File Name):                CameraController.cs作者(Author):                      TianWenQuan创建时间(CreateTime):             #CREATETIME#Unity版本(UnityVersion):         #UNITYVERSION#项目:**********************************************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
namespace Twq
{/// <summary>/// 该脚本需要挂在摄像机上/// </summary>public class CameraController : MonoBehaviour{public Transform targetObject;public Vector3 targetOffset;public float averageDistance = 5.0f;//初始位置 镜头远近public float maxDistance = 20;public float minDistance = .6f;public float xSpeed = 200.0f;public float ySpeed = 200.0f;public int yMinLimit = -80;public int yMaxLimit = 80;public int xMinLimit = -80;public int xMaxLimit = 80;public int zoomSpeed = 40;public float panSpeed = 0.3f;public float zoomDampening = 5.0f;public float rotateOnOff = 1;private float xDeg = 0.0f;private float yDeg = 0.0f;private float currentDistance;private float desiredDistance;private Quaternion currentRotation;private Quaternion desiredRotation;private Quaternion rotation;private Vector3 position;private float idleTimer = 0.0f;private float idleSmooth = 0.0f;void Start() { Init(); }void OnEnable() { Init(); }public void Init(){tt();}public void tt(){if (!targetObject){GameObject go = new GameObject("Cam Target");go.transform.position = transform.position + (transform.forward * averageDistance);targetObject = go.transform;}currentDistance = averageDistance;desiredDistance = averageDistance;position = transform.position;rotation = transform.rotation;currentRotation = transform.rotation;desiredRotation = transform.rotation;xDeg = Vector3.Angle(Vector3.right, transform.right);yDeg = Vector3.Angle(Vector3.up, transform.up);position = targetObject.position - (rotation * Vector3.forward * currentDistance + targetOffset);}void LateUpdate(){if (IsPointerOverGameObject(Input.mousePosition)){if (Input.GetMouseButton(2) && Input.GetKey(KeyCode.LeftAlt) && Input.GetKey(KeyCode.LeftControl)){desiredDistance -= Input.GetAxis("Mouse Y") * 0.02f * zoomSpeed * 0.125f * Mathf.Abs(desiredDistance);}else if (Input.GetMouseButton(0)){xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f;yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);xDeg = ClampAngle(xDeg, xMinLimit, xMaxLimit);desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);currentRotation = transform.rotation;rotation = Quaternion.Lerp(currentRotation, desiredRotation, 0.02f * zoomDampening);transform.rotation = rotation;idleTimer = 0;idleSmooth = 0;}else{//自动旋转//idleTimer += 0.02f;//if (idleTimer > rotateOnOff && rotateOnOff > 0)//{//    idleSmooth += (0.02f + idleSmooth) * 0.005f;//    idleSmooth = Mathf.Clamp(idleSmooth, 0, 1);//    xDeg += xSpeed * 0.001f * idleSmooth;//}//yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);//desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);//currentRotation = transform.rotation;//rotation = Quaternion.Lerp(currentRotation, desiredRotation, 0.02f * zoomDampening * 2);//transform.rotation = rotation;}desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * 0.02f * zoomSpeed * Mathf.Abs(desiredDistance);desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);currentDistance = Mathf.Lerp(currentDistance, desiredDistance, 0.02f * zoomDampening);position = targetObject.position - (rotation * Vector3.forward * currentDistance + targetOffset);transform.position = position;}}private static float ClampAngle(float angle, float min, float max){if (angle < -360)angle += 360;if (angle > 360)angle -= 360;return Mathf.Clamp(angle, min, max);}/// <summary>/// 检测是否点击UI/// </summary>/// <param name="mousePosition">鼠标位置</param>/// <returns></returns>private bool IsPointerOverGameObject(Vector2 mousePosition){//创建一个点击事件PointerEventData eventData = new PointerEventData(EventSystem.current);eventData.position = mousePosition;List<RaycastResult> raycastResults = new List<RaycastResult>();//向点击位置发射一条射线,检测是否点击UIEventSystem.current.RaycastAll(eventData, raycastResults);if (raycastResults.Count > 0){// Debug.Log("raycastResults[0].gameObject.name="+ raycastResults[0].gameObject.name);if (raycastResults[0].gameObject.name == "RawImage")//判断是否 是 自己要点击的UI{return true;}else{return false;}}else{return false;}}/// <summary>/// 获取鼠标停留处UI/// </summary>/// <param name="canvas"></param>/// <returns></returns>public string GetOverUI(GameObject canvas){PointerEventData pointerEventData = new PointerEventData(EventSystem.current);pointerEventData.position = Input.mousePosition;GraphicRaycaster gr = canvas.GetComponent<GraphicRaycaster>();List<RaycastResult> results = new List<RaycastResult>();gr.Raycast(pointerEventData, results);if (results.Count != 0){Debug.Log("");return results[0].gameObject.name;}return null;}}
}

 6.鼠标点击 模型 触发事件

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;namespace App.UI.Event
{public class RaycastFromMouse : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler, IDragHandler, IBeginDragHandler, IEndDragHandler{public Camera renderCamera;public RawImage rawImage;public void OnPointerClick(PointerEventData eventData){// 获取鼠标点击位置Vector2 clickPosition = eventData.position;// 将屏幕坐标转换为 RawImage 的本地坐标Vector2 localPoint;RectTransformUtility.ScreenPointToLocalPointInRectangle(rawImage.rectTransform, clickPosition, eventData.pressEventCamera, out localPoint);// 将 RawImage 的本地坐标映射到 RenderTexture 的分辨率范围内Rect rect = rawImage.rectTransform.rect;Vector2 normalizedPoint = new Vector2((localPoint.x - rect.x) / rect.width, (localPoint.y - rect.y) / rect.height);// 将转换后的坐标转换为射线Ray ray = renderCamera.ViewportPointToRay(normalizedPoint);// 发射射线,检测是否与3D模型交互RaycastHit hit;if (Physics.Raycast(ray, out hit)){// 获取物体上的 EventTrigger 组件EventTrigger eventTrigger = hit.collider.gameObject.GetComponent<EventTrigger>();// 如果组件存在,触发 Pointer Click 事件if (eventTrigger != null){ExecuteEvents.Execute(eventTrigger.gameObject, eventData, ExecuteEvents.pointerClickHandler);}}}private GameObject selectedObject;public void OnPointerDown(PointerEventData eventData){RaycastHit hit;if (RaycastToRenderTexture(eventData, out hit)){EventTrigger eventTrigger = hit.collider.gameObject.GetComponent<EventTrigger>();if (eventTrigger != null){ExecuteEvents.Execute(eventTrigger.gameObject, eventData, ExecuteEvents.pointerDownHandler);selectedObject = eventTrigger.gameObject;}}}public void OnPointerUp(PointerEventData eventData){if (selectedObject != null){EventTrigger eventTrigger = selectedObject.GetComponent<EventTrigger>();if (eventTrigger != null){ExecuteEvents.Execute(eventTrigger.gameObject, eventData, ExecuteEvents.pointerUpHandler);selectedObject = null;}}}public void OnBeginDrag(PointerEventData eventData){if (selectedObject != null){EventTrigger eventTrigger = selectedObject.GetComponent<EventTrigger>();if (eventTrigger != null){ExecuteEvents.Execute(eventTrigger.gameObject, eventData, ExecuteEvents.beginDragHandler);}}GlobalEvent.Dispatch(UIExecuteEvent.OnBeginDragEvent, eventData);}public void OnDrag(PointerEventData eventData){if (selectedObject != null){EventTrigger eventTrigger = selectedObject.GetComponent<EventTrigger>();if (eventTrigger != null){ExecuteEvents.Execute(eventTrigger.gameObject, eventData, ExecuteEvents.dragHandler);}}GlobalEvent.Dispatch(UIExecuteEvent.OnDragEvent, eventData);}public void OnEndDrag(PointerEventData eventData){if (selectedObject != null){EventTrigger eventTrigger = selectedObject.GetComponent<EventTrigger>();if (eventTrigger != null){ExecuteEvents.Execute(eventTrigger.gameObject, eventData, ExecuteEvents.endDragHandler);}}GlobalEvent.Dispatch(UIExecuteEvent.OnEndDragEvent, eventData);}private bool RaycastToRenderTexture(PointerEventData eventData, out RaycastHit hit){Vector2 clickPosition = eventData.position;Vector2 localPoint;RectTransformUtility.ScreenPointToLocalPointInRectangle(rawImage.rectTransform, clickPosition, eventData.pressEventCamera, out localPoint);Rect rect = rawImage.rectTransform.rect;Vector2 normalizedPoint = new Vector2((localPoint.x - rect.x) / rect.width, (localPoint.y - rect.y) / rect.height);Ray ray = renderCamera.ViewportPointToRay(normalizedPoint);return Physics.Raycast(ray, out hit);}}
}

相关文章:

unity 模型显示在UI上 并交互(点击、旋转、缩放)

项目工程&#xff1a;unity模型显示在UI上并交互&#xff08;点击、旋转、缩放&#xff09;资源-CSDN文库 1.在Assets创建 Render Texture&#xff08;下面会用到&#xff09;&#xff0c;根据需要设置Size 2.创建UIRawImage&#xff0c;并把Render Texture赋上 3.创建相机&am…...

html实现页面切换、顶部标签栏(可删、可切换,点击左侧超链接出现标签栏)

一、在一个页面&#xff08;不跨页面&#xff09; 效果&#xff1a; 代码 <!DOCTYPE html> <html><head><style>/* 设置标签页外层容器样式 */.tab-container {width: 100%;background-color: #f1f1f1;overflow: hidden;}/* 设置标签页选项卡的样式…...

n-皇后问题(DFS)

n−皇后问题是指将 n 个皇后放在 nn 的国际象棋棋盘上&#xff0c;使得皇后不能相互攻击到&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上。 现在给定整数 n&#xff0c;请你输出所有的满足条件的棋子摆法。 输入格式 共一行&#xff0c;包含整数 n。 输出…...

漏洞利用和权限提升

使用Kali Linux进行漏洞利用和权限提升是渗透测试过程中的一部分&#xff0c;用于评估系统的安全性。 漏洞利用&#xff1a; 选择目标&#xff1a; 首先&#xff0c;确定 要进行漏洞利用的目标系统。这可能是一个具有已知漏洞的应用程序、服务或操作系统。 收集信息&#xff…...

开源网安受邀参加软件供应链安全沙龙,推动企业提升安全治理能力

​8月23日下午&#xff0c;合肥软件行业软件供应链安全沙龙在中安创谷科技园举办。此次沙龙由合肥软件产业公共服务中心联合中安创谷科技园公司共同主办&#xff0c;开源网安软件供应链安全专家王晓龙、尹杰受邀参会并带来软件供应链安全方面的精彩内容分享&#xff0c;共同探讨…...

回归分析扫盲:为什么非线性模型不能直接用最优子集选择法

最近有人给我发了篇文章&#xff1a; 一个问题有一堆变量&#xff0c;我们要选取哪些变量来建模呢&#xff1f;我们来看看这篇文章是怎么做的&#xff1a; 这个方法简单来说就是&#xff1a;对于这一堆变量&#xff0c;我们每次尝试剔除其中一个变量&#xff0c;然后用剩下的变…...

单例模式简介

概念&#xff1a; 单例模式&#xff08;Singleton Pattern&#xff09;是一种创建型设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供全局访问点。单例模式的核心思想是限制某个类只能创建一个对象实例&#xff0c;并提供对该实例的全局访问。这样可以避免多个…...

WPF自定义命令及属性改变处理

1、项目建构 2、自定义命令 namespace WpfDemo.Base {public class MyCommand : ICommand{Action executeAction;public MyCommand(Action action){executeAction action;}public event EventHandler? CanExecuteChanged;public bool CanExecute(object? parameter){retu…...

macbook m1 docker中使用go

已经有一个centos8的镜像&#xff0c;本来打算在centos8中安装go 安装方法&#xff1a; # 1.下载go的安装包 mkdir install && cd install # 任意创建个文件夹 wget https://go.dev/dl/go1.20.2.linux-amd64.tar.gz# 2. 解压 tar -C xzf go1.20.2.linux-amd64.tar.g…...

【Hello Network】DNS协议 NAT技术 代理服务器

本篇博客简介&#xff1a;介绍DNS协议 NAT技术和代理服务器 网络各协议补充 DNSDNS背景DNS介绍DNS总结域名简介 NAT技术NAT技术背景NAT IP转换过程NAPTNAT技术缺陷NAT和代理服务器 网络协议总结应用层传输层网络层数据链路层 DNS DNS是一整套从域名映射到IP的系统 DNS背景 为…...

Android 使用模拟器模拟Linux操作系统

1. 简介 在Android手机上使用模拟器模拟ubuntu等操作系统&#xff0c;便于测试 2. 软件准备 Termux&#xff1a;是一款 Android 终端模拟器和 Linux 环境应用程序&#xff0c;无需 root 或设置即可直接运行。虽然酷安和谷歌菜市场都能下载&#xff0c;但这些渠道都很久没更新…...

机器学习基础之《分类算法(5)—朴素贝叶斯算法原理》

一、朴素贝叶斯算法 1、什么是朴素贝叶斯分类方法 之前用KNN算法&#xff0c;分类完直接有个结果&#xff0c;但是朴素贝叶斯分完之后会出现一些概率值&#xff0c;比如&#xff1a; 这六个类别&#xff0c;它都有一定的可能性 再比如&#xff0c;对文章进行分类&#xff1a;…...

# Go学习-Day6

文章目录 Go学习-Day6封装继承接口 Go学习-Day6 个人博客&#xff1a;CSDN博客 封装 类似java的类的封装&#xff0c;这里我们利用大小写和工厂模式来实现封装的功能略过 继承 相似的类具有相似的方法&#xff0c;反复绑定相同的方法&#xff0c;代码冗余&#xff0c;所以引…...

分布式 - 服务器Nginx:一小时入门系列之 HTTPS协议配置

文章目录 1. HTTPS 协议2. 生成 SSL 证书和私钥文件3. 配置 SSL 证书和私钥文件4. HTTPS 协议优化 1. HTTPS 协议 HTTPS 是一种通过计算机网络进行安全通信的协议。它是HTTP的安全版本&#xff0c;通过使用 SSL 或 TLS 协议来加密和保护数据传输。HTTPS的主要目的是确保在客户…...

探秘Linux系统性能监控神器!Linux和Python技术持续学习者必看!

引言 作为Linux运维工程师&#xff0c;我们经常需要对服务器的性能进行监控和调优。而Python作为一门强大的脚本语言&#xff0c;可以帮助我们轻松实现各种系统性能监控任务。本文将介绍几个实用的Python库和工具&#xff0c;帮助我们监控Linux系统的CPU、内存、磁盘和网络等性…...

文心一言续写太监小说《名侦探世界的巫师》

《名侦探世界的巫师》是我的童年回忆&#xff0c;总是想着续写一下&#xff0c;但是又没有时间和文笔&#xff0c;文心一言出了&#xff0c;由于目前大模型貌似可以联网&#xff0c;可以尝试搞一波~ 目录 文章1【前六个故事还能看&#xff0c;后面就是在重复】故事2【辣眼睛】…...

Solidity 合约安全,常见漏洞(第三篇)

Solidity 合约安全&#xff0c;常见漏洞&#xff08;第三篇&#xff09; ERC20 代币问题 如果你只处理受信任的 ERC20 代币&#xff0c;这些问题大多不适用。然而&#xff0c;当与任意的或部分不受信任的 ERC20 代币交互时&#xff0c;就有一些需要注意的地方。 ERC20&#…...

Linux安装Redis数据库,无需公网IP实现远程连接

文章目录 1. Linux(centos8)安装redis数据库2. 配置redis数据库3. 内网穿透3.1 安装cpolar内网穿透3.2 创建隧道映射本地端口 4. 配置固定TCP端口地址4.1 保留一个固定tcp地址4.2 配置固定TCP地址4.3 使用固定的tcp地址连接 Redis作为一款高速缓存的key value键值对的数据库,在…...

智慧政务,长远布局——AIGC引领,加速推进数字化政府建设

在人工智能、虚拟现实等领域迅猛发展且日益成熟的背景下&#xff0c;AI行业正迈向蓬勃发展的全新阶段&#xff0c;市场规模持续扩张。与此同时&#xff0c;数字服务也正在蓬勃兴起&#xff0c;新一代信息技术为数字政府构建了坚实支撑&#xff0c;重塑了政务信息化管理、业务架…...

中央处理器(CPU):组成、指令周期、数据通路、控制方式、控制器、指令流水线,补充(多处理器系统、硬件多线程)

中央处理器&#xff08;CPU&#xff0c;Central Processing Unit&#xff09;&#xff0c;计算机控制和运算的核心&#xff0c;是信息处理和程序运行的执行单元。 CPU主要功能&#xff1a;处理指令、执行操作、控制时间、处理中断、处理数据。 其中&#xff0c;处理指令、执行…...

Matlab 2020a老版本用户福音:手把手教你配置MinGW 6.3.0并集成第三方EXR工具

Matlab 2020a兼容性解决方案&#xff1a;MinGW 6.3.0与EXR工具链深度整合指南 对于长期依赖Matlab 2020a进行科研或工程开发的用户来说&#xff0c;遇到需要处理EXR图像文件的需求时往往会陷入两难——既无法放弃经过验证的稳定开发环境&#xff0c;又需要扩展功能支持。本文将…...

Python在气象与海洋中的实践技术应用

Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;能够在不同操作系统和平台使用&#xff0c;简洁的语法和解释性语言使其成为理想的脚本语言。除了标准库&#xff0c;还有丰富的第三方库&#xff0c;并且能够把用其他语言&#xff08;C/C、Fortran…...

探索中医数字化:基于深度学习的舌苔检测项目推荐

探索中医数字化&#xff1a;基于深度学习的舌苔检测项目推荐 【下载地址】基于深度学习的舌苔检测毕设留档 本项目是针对中医领域中舌象分析的一项研究&#xff0c;通过应用深度学习技术来实现自动的舌苔检测。随着人工智能在医疗健康领域的深入发展&#xff0c;利用计算机视觉…...

Sunshine开发者指南:理解项目架构和代码实现原理

Sunshine开发者指南&#xff1a;理解项目架构和代码实现原理 【免费下载链接】sunshine Host for Moonlight Streaming Client 项目地址: https://gitcode.com/gh_mirrors/sun/sunshine Sunshine是一个开源的游戏串流主机项目&#xff0c;专为Moonlight客户端设计。作为…...

终极指南:5步掌握MPh,让COMSOL仿真效率提升300%

终极指南&#xff1a;5步掌握MPh&#xff0c;让COMSOL仿真效率提升300% 【免费下载链接】MPh Pythonic scripting interface for Comsol Multiphysics 项目地址: https://gitcode.com/gh_mirrors/mp/MPh MPh&#xff08;Pythonic scripting interface for Comsol Multip…...

好想来万店扩张背后的数据新底座

在中国量贩零食行业的版图上&#xff0c;好想来正以雷霆之势重塑市场格局。作为万辰集团旗下的头部品牌&#xff0c;好想来已在全国布局超过 1.5 万家门店&#xff0c;注册会员超过 1.5 亿&#xff0c;年营收突破 365 亿元&#xff0c;成为名副其实的零售巨擘。这些令人瞩目的数…...

别再只用ARIMA了!用Python+statsmodels搞定SARIMA预测电商销量(附完整代码)

电商销量预测实战&#xff1a;用PythonSARIMA破解季节性销售波动 电商销量预测的痛点与SARIMA的破局之道 每逢大促季节&#xff0c;电商运营团队总会陷入两难困境&#xff1a;备货不足错失销售良机&#xff0c;库存积压又导致资金周转困难。传统ARIMA模型在预测日常销量时表现尚…...

你的STM32调试信息用对了吗?深入对比.axf文件与addr2line.exe的配合之道

STM32调试进阶&#xff1a;解密.axf文件与addr2line的黄金组合 调试嵌入式系统时&#xff0c;最令人沮丧的莫过于设备突然崩溃&#xff0c;而你却对问题源头一无所知。作为一名长期与STM32打交道的开发者&#xff0c;我经历过无数次这样的时刻&#xff0c;直到真正理解了调试信…...

DNS 与 hosts 文件:Windows 11 中的名称解析配置

诸神缄默不语-个人技术博文与视频目录 一个域名会对应多个IP地址&#xff0c;当电脑访问域名时会默认指定访问其中一个IP地址&#xff08;以下正文会介绍通过hosts文件和DNS服务器选择指定映射的IP的原理&#xff09;&#xff0c;总之有时我们可能会需要将域名对应的IP地址指定…...

从CLIP到多模态:对比学习驱动的视觉-语言模型演进与实战

1. 对比学习&#xff1a;CLIP的基石与多模态革命 我第一次接触CLIP模型是在2021年初&#xff0c;当时OpenAI发布的这篇论文彻底颠覆了我对视觉模型训练方式的认知。传统计算机视觉任务总是离不开人工标注的海量数据&#xff0c;而CLIP却另辟蹊径&#xff0c;用自然语言作为监督…...