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

Unity自定义数组在Inspector窗口的显示方式

了解

  1. 单行高度:EditorGUIUtility.singleLineHeight
  2. 获取 PropertyField 控件所需的高度:EditorGUI.GetPropertyHeight
  3. 属性是否在Inspector窗口展开:SerializedProperty.isExpanded
  4. 可重新排序列表类:ReorderableList
  5. 绘制纯色矩形:EditorGUI.DrawRect

示例

使用版本:2021.3.6f1c1
此版本的Unity已经实现数组元素添加,移除,移动功能。

自定义类

[System.Serializable]
public class Test 
{public string name;public int age;
}

数据类

定义一个数组,数组元素为自定义类

using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu]
public class TestSO : ScriptableObject
{public List<Test> testList;
}

数据类文件默认显示如下

在这里插入图片描述

修改数据类显示

数据元素内容显示为一行

注意:不能使用自动布局api

using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(Test))]
public class TestDrawer : PropertyDrawer
{public override void OnGUI(Rect position, SerializedProperty property, GUIContent label){var spName = property.FindPropertyRelative("name");var spAge = property.FindPropertyRelative("age");var rect1 = position;var rect2 = position;var indentlevel = EditorGUI.indentLevel;var lableWidth = EditorGUIUtility.labelWidth;EditorGUI.indentLevel = 2;EditorGUIUtility.labelWidth = 60;rect1.width = position.width / 2;rect1.height = EditorGUIUtility.singleLineHeight;rect2.width = position.width / 2;rect2.height = EditorGUIUtility.singleLineHeight;rect2.x = position.width / 2+40;rect2.y = rect1.y;EditorGUI.PropertyField(rect1, spName, new GUIContent("名字"));EditorGUI.PropertyField(rect2, spAge, new GUIContent("年龄"));EditorGUI.indentLevel = indentlevel;EditorGUIUtility.labelWidth = lableWidth;//EditorGUI.DrawRect(rect1, Color.green);//EditorGUI.DrawRect(rect2, Color.gray);}//获取属性高度public override float GetPropertyHeight(SerializedProperty property, GUIContent label){return base.GetPropertyHeight(property, label);}
}

修改后显示效果如下图所示
在这里插入图片描述

TestList修改为指定名称;Element修改为指定名称

using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
[CustomEditor(typeof(TestSO))]
public class TestSOEditor : Editor
{SerializedProperty sPTestList;ReorderableList arrayList;private void OnEnable(){sPTestList = serializedObject.FindProperty("testList");if (arrayList == null){arrayList = new ReorderableList(serializedObject, sPTestList, true, true, true, true);    //绘制HeaderarrayList.drawHeaderCallback += DrawHeader;//绘制数组元素arrayList.drawElementCallback += DrawElement;//获取数组的高度arrayList.elementHeightCallback += DrawElementHeight;}}void DrawHeader(Rect rect){EditorGUI.LabelField(rect, "测试列表");}void DrawElement(Rect rect, int index, bool isActive, bool isFocused){var element = sPTestList.GetArrayElementAtIndex(index);var arrowRect = rect;int indentLevel = EditorGUI.indentLevel;EditorGUI.indentLevel = 1;arrowRect.height = EditorGUIUtility.singleLineHeight;element.isExpanded = EditorGUI.Foldout(arrowRect, element.isExpanded, new GUIContent("元素" + index));EditorGUI.indentLevel = indentLevel;//EditorGUI.DrawRect(rect, Color.red);//EditorGUI.DrawRect(arrowRect, Color.blue);if (element.isExpanded){rect.y += arrowRect.height;EditorGUI.PropertyField(rect, element);}}float DrawElementHeight(int index){var element = sPTestList.GetArrayElementAtIndex(index);var height = EditorGUIUtility.singleLineHeight;//折叠箭头的高度   if (element.isExpanded)//如果元素展开 获取展开内容的高度和箭头的高度之和height += EditorGUI.GetPropertyHeight(element);return height;}public override void OnInspectorGUI(){serializedObject.Update();arrayList.DoLayoutList();serializedObject.ApplyModifiedProperties();}
}

修改后如下图所示
在这里插入图片描述

示例二

高度计算放在PropertyDrawer的OnGUI中

自定义类

显示折叠箭头,数据元素内容显示为一行,Element修改为指定名称

using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(Test))]
public class TestDrawer : PropertyDrawer
{public override void OnGUI(Rect position, SerializedProperty property, GUIContent label){var spName = property.FindPropertyRelative("name");var spAge = property.FindPropertyRelative("age");var rect0 = position;rect0.height = EditorGUIUtility.singleLineHeight;var indentlevel = EditorGUI.indentLevel;EditorGUI.indentLevel = 1;property.isExpanded = EditorGUI.Foldout(rect0, property.isExpanded, label);EditorGUI.indentLevel = indentlevel;if (property.isExpanded){var rect1 = position;var rect2 = position;indentlevel = EditorGUI.indentLevel;var lableWidth = EditorGUIUtility.labelWidth;EditorGUI.indentLevel = 2;EditorGUIUtility.labelWidth = 60;rect1.width = position.width / 2;rect1.height = EditorGUIUtility.singleLineHeight;rect1.y += EditorGUIUtility.singleLineHeight;rect2.width = position.width / 2;rect2.height = EditorGUIUtility.singleLineHeight;rect2.x = position.width / 2 + 40;rect2.y = rect1.y;EditorGUI.PropertyField(rect1, spName, new GUIContent("名字"));EditorGUI.PropertyField(rect2, spAge, new GUIContent("年龄"));EditorGUI.indentLevel = indentlevel;EditorGUIUtility.labelWidth = lableWidth;//EditorGUI.DrawRect(rect1, Color.green);//EditorGUI.DrawRect(rect2, Color.gray);}}public override float GetPropertyHeight(SerializedProperty property, GUIContent label){if (property.isExpanded)return EditorGUIUtility.singleLineHeight * 2;elsereturn EditorGUIUtility.singleLineHeight;}
}

数据类

TestList修改为指定名称

using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
[CustomEditor(typeof(TestSO))]
public class TestSOEditor : Editor
{SerializedProperty sPTestList;ReorderableList arrayList;private void OnEnable(){sPTestList = serializedObject.FindProperty("testList");if (arrayList == null){arrayList = new ReorderableList(serializedObject, sPTestList, true, true, true, true);//绘制HeaderarrayList.drawHeaderCallback += DrawHeader;//绘制数组元素arrayList.drawElementCallback += DrawElement;//绘制元素高度arrayList.elementHeightCallback += DrawHeight;void DrawHeader(Rect rect){EditorGUI.LabelField(rect, "测试列表");}void DrawElement(Rect rect, int index, bool isActive, bool isFocused){//参数会传递给PropertyDrawer的OnGUI EditorGUI.PropertyField(rect, sPTestList.GetArrayElementAtIndex(index), new GUIContent("元素 " + index));}float DrawHeight(int index){return EditorGUI.GetPropertyHeight(sPTestList.GetArrayElementAtIndex(index));}}}public override void OnInspectorGUI(){serializedObject.Update();arrayList.DoLayoutList();serializedObject.ApplyModifiedProperties();}
}

参考

看完后理解列表的高度如何计算

相关文章:

Unity自定义数组在Inspector窗口的显示方式

了解 单行高度:EditorGUIUtility.singleLineHeight获取 PropertyField 控件所需的高度:EditorGUI.GetPropertyHeight属性是否在Inspector窗口展开&#xff1a;SerializedProperty.isExpanded可重新排序列表类&#xff1a;ReorderableList绘制纯色矩形&#xff1a;EditorGUI.Dr…...

ERC论文阅读(03)--SPCL论文阅读笔记(2024-10-29)

SPCL论文阅读笔记 论文中心思想 这篇论文是研究ERC任务的论文&#xff0c;作者提出了监督原型对比学习的方法用于ERC任务。 论文 EMNLP2022 paper “Supervised Prototypical Contrastive Learning for Emotion Recognition in Conversation” 现存问题 现存的使用监督对…...

Straightforward Layer-wise Pruning for More Efficient Visual Adaptation

对于模型中冗余的参数&#xff0c;一个常见的方法是通过结构化剪枝方法减少参数容量。例如&#xff0c;基于幅度值和基于梯度的剪枝方法。尽管这些方法在传统训练上通用性&#xff0c;本文关注的PETL迁移有两个不可避免的问题&#xff1a; 显著增加了模型存储负担。由于不同的…...

喜讯 | 创邻科技杭州电子科技大学联合实验室揭牌成立!

近日&#xff0c;杭州电子科技大学图书情报专业硕士行业导师聘任仪式暨杭电-创邻图技术与数字化联合实验室&#xff08;图书档案文物数字云联合研发中心&#xff09;揭牌仪式在杭州电子科技大学隆重举行。杭州电子科技大学原副校长吕金海、研究生院副院长潘建江&#xff0c;科研…...

海外媒体发稿:如何打造媒体发稿策略

新闻媒体的发稿推广策略对于提升品牌知名度、吸引流量以及增加收入非常重要。本文将介绍一套在21天内打造爆款新闻媒体发稿推广策略的方法。 第一天至第七天&#xff1a;明确目标和定位 在这个阶段&#xff0c;你需要明确你的目标和定位&#xff0c;以便为你的新闻媒体建立一个…...

PyTorch模型保存与加载

1.保存与加载的概念(序列化与反序列化) 模型训练完毕之后,肯定想要把它保存下来,供以后使用,不需要再次去训练。 那么在pytorch中如何把训练好的模型,保存,保存之后又如何加载呢? 这就用需要序列化与反序列化,序列化与反序列化的概念如下图所示: 因为在内…...

CH569开发前的测试

为了玩转准备Ch569的开发工作 &#xff0c;准备了如下硬件和软件&#xff1a; 硬件 1.官方的 Ch569 开发板&#xff0c;官方买到的是两块插接在一起的&#xff1b;除了HSPI接口那里的电阻&#xff0c;这两块可以说是一样的。也意味着两块板子的开发也需要烧录两次&#xff1b…...

MySQL中表的外连接和内连接

内连接和外连接 ​ 表的连接分为内连接和外连接&#xff0c;内连接就是将需要连接的表形成笛卡尔积筛选&#xff1b;外连接分为左外连接和右外连接&#xff0c;左外连接为左侧的表需要完全显示&#xff0c;右外连接为右侧的表现需要完全显示。 文章目录 内连接和外连接内连接外…...

Ubuntu 上安装 Redmine 5.1 指南

文章目录 官网安装文档&#xff1a;命令步骤相关介绍GemRubyRailsBundler 安装 Redmine更新系统包列表和软件包&#xff1a;安装必要的依赖&#xff1a;安装 Ruby&#xff1a;安装 bundler下载 Redmine 源代码&#xff1a;安装 MySQL配置 Redmine 的数据库配置文件&#xff1a;…...

从变量的角度理解 Hooks , 变得更简单了

从变量角度理解Hooks 在React的世界里&#xff0c;Hooks的引入为函数式组件带来了前所未有的灵活性和能力。它们让我们得以完全摆脱class式的写法&#xff0c;在函数式组件中完成生命周期管理、状态管理、逻辑复用等几乎全部组件开发工作。这次&#xff0c;我们就从变量的角度…...

LabVIEW Modbus通讯稳定性提升

在LabVIEW开发Modbus通讯程序时&#xff0c;通讯不稳定是一个常见问题&#xff0c;可能导致数据丢失、延迟或错误。为了确保通讯的可靠性&#xff0c;可以从多个角度进行优化&#xff0c;以下是一些有效的解决方案&#xff0c;结合实际案例进行分析。 1. 优化通讯参数设置 通讯…...

(8) cuda分析工具

文章目录 Nvidia GPU性能分析工具Nsight SystemNvidia GPU性能分析工具Nsight System Nvidia GPU性能分析工具Nsight System NVIDIA Nsight Systems是一个系统级的性能分析工具&#xff0c;用于分析和优化整个CUDA应用程序或系统的性能。它可以提供对应用程序整体性能的全面见…...

C语言 | Leetcode C语言题解之第517题超级洗衣机

题目&#xff1a; 题解&#xff1a; int findMinMoves(int* machines, int machinesSize){int sum0;for(int i0;i<machinesSize;i){summachines[i];}if(sum%machinesSize!0){return -1;}int psum/machinesSize;int ans0;int cur0;for(int i0;i<machinesSize;i){cur(mac…...

Java多线程编程基础

目录 编写第一个多线程程序 1. 方式一 : 继承Thread类, 重写run方法 2. 方式二: 实现Runnable接口, 重写run方法 3. 方式三: 使用Lambda表达式 [匿名内部类] [Lambda表达式] 在上个文章中, 我们了解了进程和线程的相关概念. 那么, 在Java中, 我们如何进行多线程编程呢? …...

刷代随有感(134):单调栈——下一个更大元素I(难点涉及哈希表与单调栈的结合)

单调栈处理的是下标&#xff01; 题干&#xff1a; 代码&#xff1a; class Solution { public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {stack<int>ddst;unordered_map<int,int>umap;vector<int…...

Linux云计算 |【第五阶段】CLOUD-DAY5

主要内容&#xff1a; 容器的镜像编排&#xff0c;commit简单镜像创建&#xff0c;Dockerfile制作服务镜像&#xff08;语法、创建镜像&#xff09;、创建复杂镜像&#xff08;Docker微服务架构、示例&#xff1a;NGINXPHP&#xff09;、私有仓库 一、简单镜像创建 1、自定义…...

被上传文件于后端的命名策略

上一篇博客我们了解了前端上传的文件资源应该存放在后端项目中的什么位置&#xff0c;那么随之而来的另一个问题——我们应该如何为上传的文件命名呢&#xff1f;往往直接采用原文件名并不稳妥&#xff0c;会导致命名冲突、文件冲突、数据库管理冲突等多种问题&#xff0c;下面…...

哈希表 算法专题

哈希表简介 是什么 存储数据的容器有啥用? "快速"查找某个元素什么时候用哈希表 频繁地查找某个数(有序用二分)怎么用哈希表 容器用数组模拟 字符串中的字符 范围比较小的数 一. 两数之和 两数之和 class Solution {public int[] twoSum(int[] nums, int targe…...

unity3d————[HideInInspector]

在Unity3D中&#xff0c;[HideInInspector]是一个属性修饰符&#xff0c;它的主要作用是在Unity的Inspector窗口中隐藏变量或属性。以下是关于[HideInInspector]的详细解释和作用&#xff1a; 作用 隐藏变量或属性&#xff1a;当你在脚本中使用[HideInInspector]修饰符时&…...

Soanrquber集成Gitlab 之 导入Gitlab项目

集成Gitlab 之 导入Gitlab项目 说明&#xff1a; Sonarquber里面的项目&#xff0c;顺便设置&#xff0c;只要在集成CI的时候&#xff0c;使用这个项目的项目标识即可。 当然项目名称一一对应是最好的了&#xff0c;所以这里讲导入Gitlab的项目&#xff0c;项目名称一一对应&…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...