当前位置: 首页 > 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;项目名称一一对应&…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

Linux 下 DMA 内存映射浅析

序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存&#xff0c;但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程&#xff0c;可以参考这篇文章&#xff0c;我觉得写的非常…...

leetcode73-矩阵置零

leetcode 73 思路 记录 0 元素的位置&#xff1a;遍历整个矩阵&#xff0c;找出所有值为 0 的元素&#xff0c;并将它们的坐标记录在数组zeroPosition中置零操作&#xff1a;遍历记录的所有 0 元素位置&#xff0c;将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...