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

第三章自定义检视面板_创建自定义编辑器类_如何自定义预览窗口(本章进度5/9)

3.1.5 如何自定义预览窗口

在unity中我们经常会用到预览窗口,如下图,去查看一些东西。比如模型、动画之类。
在这里插入图片描述

书上提供是一个例子使用与DoTween结合做了动画相关的一个预览窗口。内容比较多,总共代码五百多行,不适合在这里讲,我会在专栏的最后,把所有例子解析一下,因为我感觉例子里的其他东西都太多了,我只想介绍简单预览窗口,我会举个简单例子,实现一个可以鼠标旋转缩放的预览窗口。

它的逻辑流程图是这样的
在这里插入图片描述

代码实现

using UnityEngine;
using UnityEditor;// 使用 CustomEditor 特性指定这个编辑器用于 Transform 组件
[CustomEditor(typeof(Transform))]
public class ObjectPreviewEditor : Editor
{// 预览渲染工具 - 用于创建和管理预览窗口private PreviewRenderUtility previewRenderUtility;// 预览对象实例 - 目标对象的副本private GameObject previewInstance;// 相机旋转角度 - 存储鼠标拖拽的旋转值private Vector2 rotation;// 相机距离 - 控制预览的缩放private float distance = 5f;/// <summary>/// 当编辑器启用时调用 - 初始化预览系统/// </summary>private void OnEnable(){// 创建预览渲染工具实例previewRenderUtility = new PreviewRenderUtility();// 创建目标对象的副本作为预览对象// target 是当前选中的组件(这里是 Transform)previewInstance = Instantiate((target as Component).gameObject);// 设置隐藏标志 - 防止预览对象出现在场景中previewInstance.hideFlags = HideFlags.HideAndDontSave;// 将预览对象添加到渲染系统previewRenderUtility.AddSingleGO(previewInstance);// 自动计算初始相机距离CalculateInitialDistance();}/// <summary>/// 计算初始相机距离 - 根据对象大小自动调整/// </summary>private void CalculateInitialDistance(){// 创建初始边界框Bounds bounds = new Bounds();// 获取所有子物体的渲染器Renderer[] renderers = previewInstance.GetComponentsInChildren<Renderer>();// 遍历所有渲染器,计算总边界foreach (Renderer renderer in renderers){bounds.Encapsulate(renderer.bounds);}// 根据边界大小设置初始距离float size = bounds.size.magnitude;distance = Mathf.Clamp(size * 1.5f, 2f, 10f);}/// <summary>/// 当编辑器禁用时调用 - 清理资源/// </summary>private void OnDisable(){// 清理预览渲染工具if (previewRenderUtility != null){previewRenderUtility.Cleanup();}// 销毁预览对象if (previewInstance != null){DestroyImmediate(previewInstance);}}/// <summary>/// 是否显示预览窗口 - 仅在预览对象存在时返回 true/// </summary>public override bool HasPreviewGUI(){return previewInstance != null;}/// <summary>/// 绘制预览窗口 - 核心渲染方法/// </summary>/// <param name="r">预览窗口的矩形区域</param>/// <param name="background">背景样式</param>public override void OnPreviewGUI(Rect r, GUIStyle background){// 如果预览对象不存在,直接返回if (previewInstance == null)return;// 处理用户输入(旋转和缩放)HandleInput(r);// 在重绘事件中执行渲染if (Event.current.type == EventType.Repaint){// 开始预览渲染previewRenderUtility.BeginPreview(r, background);// 获取预览相机Camera camera = previewRenderUtility.camera;// 设置相机旋转(基于鼠标拖拽的角度)camera.transform.rotation = Quaternion.Euler(new Vector3(-rotation.y, -rotation.x, 0));// 设置相机位置(以对象为中心,根据距离计算)camera.transform.position = previewInstance.transform.position +camera.transform.forward * -distance;// 执行渲染camera.Render();// 结束并绘制预览previewRenderUtility.EndAndDrawPreview(r);}}/// <summary>/// 处理预览窗口的用户输入/// </summary>/// <param name="area">预览窗口的矩形区域</param>private void HandleInput(Rect area){// 获取当前事件Event e = Event.current;// 鼠标左键拖拽 - 旋转视图if (e.type == EventType.MouseDrag && e.button == 0){// 更新旋转角度(根据鼠标移动增量)rotation -= e.delta * 0.5f;// 标记事件已处理e.Use();}// 滚轮滚动 - 缩放视图if (e.type == EventType.ScrollWheel){// 根据滚轮增量调整距离distance += e.delta.y * 0.1f;// 限制距离范围distance = Mathf.Clamp(distance, 1f, 20f);// 标记事件已处理e.Use();}}
}

效果
在这里插入图片描述

http://www.lryc.cn/news/594603.html

相关文章:

  • C++基于libmodbus库实现modbus TCP/RTU通信
  • 个人中心产品设计指南:从信息展示到用户体验的细节把控
  • 第三章自定义检视面板_创建自定义编辑器类_编扩展默认组件的显示面板(本章进度3/9)
  • Jenkins 不同节点间文件传递:跨 Job 与 同 Job 的实现方法
  • 修复echarts由4.x升级5.x出现地图报错echarts/map/js/china.js未找到
  • 人形机器人CMU-ASAP算法理解
  • QGIS、ArcMap、ArcGIS Pro中的书签功能、场景裁剪
  • ruoyi-flowable-plus Excel 导入数据 Demo
  • 现在希望用git将本地文件test目录下的文件更新到远程仓库指定crawler目录下,命名相同的文件本地文件将其覆盖
  • 自动驾驶中各传感器的优缺点
  • 一个月掌握数据结构与算法:高效学习计划
  • uni-app 鸿蒙平台条件编译指南
  • vxe-table 通过配置 ajax 方式自动请求数据,适用于简单场景的列表
  • 网络基础1-11综合实验(eNSP):vlan/DHCP/Web/HTTP/动态PAT/静态NAT
  • MTSC2025参会感悟:大模型 + CV 重构全终端 UI 检测技术体系
  • C语言:深入理解指针(3)
  • cocos中实现3d人物角色头顶信息跟随功能,UI跟随3D/2D对象移动,例如昵称血条跟随人物移动
  • 【VASP】机器学习势概述
  • 智能合约安全 - 重入攻击 - 常见漏洞(第一篇)
  • taro微信小程序的tsconfig.json文件说明
  • Taro 本地存储 API 详解与实用指南
  • Typecho目录树插件开发:从后端解析到前端渲染全流程
  • 使用pymongo进行MongoDB的回收
  • Kali MSF渗透Windows 11电脑
  • Taro 路由相关 API 详解与实战
  • taro+pinia+小程序存储配置持久化
  • 微美全息(WIMI.US)聚焦多元哈希锁机制,为链上链下数据可信交互按下加速键
  • 快速入门SwiftUI
  • 【大模型】结构化提示词:让AI高效完成复杂任务的“编程语言”
  • JavaEE初阶第十期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(八)