当前位置: 首页 > 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;处理指令、执行…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...