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);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/53202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker安装并配置Pushgateway

Linux下安装Docker请参考&#xff1a;Linux安装Docker 简介 Pushgateway是Prometheus的一个组件&#xff0c;prometheus server默认是通过Exporter主动获取数据&#xff08;默认采取pull拉取数据&#xff09;&#xff0c;Pushgateway则是通过exporter主动方式推送数据到Pushg…

前端需要理解的CSS知识

CSS&#xff08;层叠样式表&#xff0c;Cascading Style Sheets&#xff09;不是编程语言&#xff0c;而是用来描述 HTML 或 XML&#xff08;包括如 SVG、MathML 或 XHTML 之类的 XML 分支语言&#xff09;文档的表现与展示效果的样式表语言。CSS3是CSS的最新标准&#xff0c;是…

mysql基础——认识索引

一、介绍 “索引”是为了能够更快地查询数据。比如一本书的目录&#xff0c;就是这本书的内容的索引&#xff0c;读者可以通过在目录中快速查找自己想要的内容&#xff0c;然后根据页码去找到具体的章节。 二、优缺点 优势&#xff1a;以快速检索&#xff0c;减少I/O次数&am…

【Go语言】基于Socket编程的P2P通信程序示例

Go语言的Socket编程实现为开发者提供了一种高效且强大的方式来实现网络通信。通过Go语言的并发模型和内置的网络库&#xff0c;如net包&#xff0c;开发者可以轻松地创建基于套接字的通信应用。Go语言的goroutine和channel机制使并发处理变得简单&#xff0c;能够轻松处理多个连…

U盘怎么加密?U盘加密方法有哪些?

U盘是我们生活和工作中最常用的移动储存设备&#xff0c;经常被用来存放各种重要数据&#xff0c;为了保证数据的安全&#xff0c;我们需要加密U盘。那么&#xff0c;U盘加密方法有哪些呢&#xff1f; U盘加密普通方法 如果你的U盘储存数据不多&#xff0c;并且对于加密的要求…

Linux 系统下 GDB 调试器的使用

文章目录 简介GDB 的介绍GDB 的使用 GDB 常用命令及示例查看相关操作断点相关操作运行相关操作变量相关操作分隔窗口操作 简介 GDB 的介绍 GDB 是 GNU 调试程序&#xff0c;是用来调试 C 和 C 程序的调试器。它可以让程序开发者在程序运行时观察程序的内部结构和内存的使用情况…

初阶c语言:趣味扫雷游戏

目录 前言 制作菜单 构建游戏选择框架 实现游戏功能 模块化编程&#xff1a;查看前节三子棋的内容 初始化雷区 ​编辑 优化棋盘 随机埋入地雷 点击后的决策 实现此功能代码 game&#xff08;&#xff09;&#xff1b;的安排 前言 《扫雷》是一款大众类的益智小游戏&…

java八股文面试[JVM]——元空间

JAVA8为什么要增加元空间 为什么要移除永久代&#xff1f; 知识来源&#xff1a; 【2023年面试】JVM8为什么要增加元空间_哔哩哔哩_bilibili

Django 简易PACS读片系统

1、Django中写一个后端接口&#xff0c;给HTML提供dicom文件接口的方式 1、首先创建django项目 1、下载安装跨域的包 pip3 install django-cors-headers2、使用pycharm创建一个Django项目 3、点击创建在另一个窗口&#xff0c;这个都无所谓&#xff0c;怎么都行&#xff0c;…

Hadoop Yarn 配置多队列的容量调度器

文章目录 配置多队列的容量调度器多队列查看 配置多队列的容量调度器 首先&#xff0c;我们进入 Hadoop 的配置文件目录中&#xff08;$HADOOP_HOME/etc/hadoop&#xff09;&#xff1b; 然后通过编辑容量调度器配置文件 capacity-scheduler.xml 来配置多队列的形式。 默认只…

安防监控平台EasyCVR视频汇聚平台增加首页告警类型的详细介绍

安防监控/视频集中存储/云存储EasyCVR视频汇聚平台&#xff0c;可支持海量视频的轻量化接入与汇聚管理。平台能提供视频存储磁盘阵列、视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、平台级联、H.265自动转码等…

基于智和网管平台的网络安全运维解决方案

随着信息技术的快速发展及网络应用的广泛普及&#xff0c;企业在享受网络技术带来便利的同时&#xff0c;也受到日益严重的网络安全威胁。未来&#xff0c;企业信息系统规模和复杂程度将不断增大&#xff0c;对信息通信技术的应用也将不断深入&#xff0c;网络安全运维将成为愈…

浅谈小程序开源业务架构建设之路

一、业务介绍 1.1 小程序开源整体介绍 百度从做智能小程序的第一天开始就打造真正开源开放的生态&#xff0c;我们的愿景是&#xff1a;定义移动时代最佳体验&#xff0c;建设智能小程序行业标准&#xff0c;打破孤岛&#xff0c;共建开源、开放、繁荣的小程序行业生态。百度智…

webrtc学习(七)-媒体协商

一.概述 媒体协商嘴主要的作用就是看通信双方都支持那些编解码器&#xff0c;这些编解码器又包含那些参数&#xff0c;比如音频的参数包括采样率&#xff0c;采样大小&#xff0c;通道数&#xff0c;对于视频的参数包括分辨率帧率等一系列参数&#xff0c;此外传输中用的payloa…

Linux 发行版 Debian 宣布支持龙芯 LoongArch 架构

近期&#xff0c;龙芯发布了 3A6000 桌面处理器&#xff0c;芯片的性能又一次大幅度提升&#xff0c;成为国产芯片的又一里程碑。 同期&#xff0c;LoongArch 架构的生态建设也迅速提升&#xff0c;开源网络引导固件 iPXE、QQ Linux 版、摩尔线程等软硬件都官宣支持龙芯 Loong…

VMware 修改ip地址 虚拟机静态ip设置 centos动态ip修改为静态ip地址 centos静态ip地址 vmware修改ip地址

虚拟机的centos服务器经常变换ip&#xff0c;测试起来有些麻烦&#xff0c;故将动态ip修改为静态ip 1. 查看vmware 虚拟机网络配置&#xff1a; 点击编辑&#xff0c;打开虚拟网络配置 2. 选中nat模式&#xff0c;点击nat设置&#xff0c;最终获取网关ip: 192.168.164.2 3. 进…

拒绝摆烂!C语言练习打卡第六天

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;每日一练 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、选择题 &#x1f4dd;1.第一题 &#x1f4dd;2.第二题 &#x1f4d…

Golang struct 结构体注意事项和使用细节

结构体所有字段在内存当中是连续的 type Point struct {x, y int }type Rect struct {leftUp, rightDown Point }func main() {//r1会在内存当中有四个整数r1 : Rect{leftUp: Point{x: 1,y: 2,},rightDown: Point{x: 3,y: 4,},}//r1有四个int&#xff0c;在内存当中是连续分布的…

基于Java+SpringBoot+Vue前后端分离社区智慧养老监护管理平台设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

Python——列表(list)推导式

本文基于python3。 目录 1、Python推导式2、列表(list)推导式2.1、定义2.2、实际操作2.2.1、一个表达式&#xff0c;后面为一个 for 子句2.2.2、一个表达式&#xff0c;后面为一个 for 子句&#xff0c;然后&#xff0c;跟着if 子句。2.2.3、一个表达式&#xff0c;后面为一个…