Unity编辑拓展显示自定义类型

devtools/2025/1/24 18:34:47/

        配合自定义特性或着header可以添加注解

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Reflection;
using System;
using Unity.VisualScripting;#if UNITY_EDITORpublic class EditorRender
{public static Enum RenderEnum(FieldInfo fieldInfo, Enum value, Type type, params GUILayoutOption[] style){var array = Enum.GetValues(type);// 直接使用  Enum[] EnumValueArr =   (Enum[])Enum.GetValues(type);  不行,这里不能用enum,存在类型转换异常,只能指定枚举类型Enum[] EnumValueArr = new Enum[array.Length];for (int i = 0; i < array.Length; i++){EnumValueArr[i] = (Enum)Enum.Parse(type, array.GetValue(i).ToString());}int[] IntValueArr = new int[EnumValueArr.Length];string[] EnumDescArr = new string[EnumValueArr.Length];for (int i = 0; i < EnumValueArr.Length; i++){Enum e = EnumValueArr[i];IntValueArr[i] = (int)Enum.Parse(type, e.ToString());var field = type.GetField(e.ToString());HeaderAttribute header = field.GetAttribute<HeaderAttribute>();if (header != null){EnumDescArr[i] = header.header;}else{EnumDescArr[i] = "未定义";}}int selectValue = (int)Enum.Parse(type, value.ToString());selectValue = EditorGUILayout.IntPopup(selectValue, EnumDescArr, IntValueArr, style);value = (Enum)Enum.Parse(type, selectValue.ToString());return value;}public static object RenderValue(FieldInfo fieldInfo, Type type, object value, object defaultValue = null, params GUILayoutOption[] style){SetDefaultValue(type, ref value, defaultValue);if (type == typeof(int)){return EditorGUILayout.IntField(int.Parse(value.ToString()), style);}else if (type == typeof(float)){return EditorGUILayout.FloatField(float.Parse(value.ToString()), style);}else if (type == typeof(long)){return EditorGUILayout.LongField(long.Parse(value.ToString()), style);}else if (type == typeof(string)){return GUILayout.TextArea(value as string, style);}else if (type == typeof(bool)){return GUILayout.Toggle(bool.Parse(value.ToString()), "", style);}else if (type.IsEnum){value = EditorRender.RenderEnum(fieldInfo, (Enum)value, type, style);return value;}else if (value is IList){value = RenderList(type.GetGenericArguments()[0], value as IList);return value;}if (value == null){return Activator.CreateInstance(type);}return null;}public static object RenderList(Type type, IList list){if (list == null){return Activator.CreateInstance(typeof(List<>).MakeGenericType(type));}for (int i = 0; i < list.Count; i++){list[i] = RenderValue(null, type, list[i], style: GUILayout.MaxWidth(400));if (GUILayout.Button("X", GUILayout.MaxWidth(50))){list.RemoveAt(i);GUILayout.EndHorizontal();break;}}GUILayout.BeginHorizontal();GUILayout.FlexibleSpace();if (GUILayout.Button("Add", GUILayout.MaxWidth(500))){list.Add(Activator.CreateInstance(type));}GUILayout.EndHorizontal();return list;}public static void SetDefaultValue(Type type, ref object value, object defaultValue){if (value == null || string.IsNullOrEmpty(value.ToString())){if (defaultValue != null){value = defaultValue;return;}if (type == typeof(int)){value = 0;}else if (type == typeof(float)){value = 0;}else if (type == typeof(long)){value = 0;}else if (type == typeof(Single)){value = 0;}else if (type == typeof(string)){value = string.Empty;}else if (type == typeof(bool)){value = false;}else if (type == typeof(Vector3)){value = Vector3.zero;}else if (type == typeof(Vector2)){value = Vector2.zero;}else if (type.IsEnum){}}}public static object RenderField(FieldInfo fieldInfo, HeaderAttribute header, object obj, params GUILayoutOption[] style){GUILayout.BeginHorizontal(GUI.skin.button);GUILayout.BeginVertical();Type t = fieldInfo.FieldType;GUILayout.Label($"{fieldInfo.Name}({t.Name})");if (header!= null){GUILayout.Label(header.header);}GUILayout.EndVertical();var value = RenderValue(fieldInfo, t, obj, style: style);GUILayout.EndHorizontal();return value;}public static object RenderObject(object value){var propertyInfos = value.GetType().GetFields();for (int i = 0; i < propertyInfos.Length; i++){var property = propertyInfos[i];object obj = property.GetValue(value);obj = EditorRender.RenderField(property, null, obj, GUILayout.MaxWidth(400));property.SetValue(value, obj);GUILayout.Space(5);}return value;}
}#endif

        使用方式,直接调用RenderObject就行

    private class CustomClass{public string Name;public int Age;public bool Sex;}private CustomClass m_CustomClass;private void OnGUI(){m_CustomClass = (CustomClass)EditorRender.RenderObject(m_CustomClass);}

        这里用的都是变量,如果使用属性的话,将获取属性,获取属性值,写入属性值的方式修改源代码即可,RenderValue里如果有未定义其他类型,记得补充


http://www.ppmy.cn/devtools/153202.html

相关文章

C语言二级

//请编写函数fun()&#xff0c;该函数的功能是&#xff1a;计算并输出给定整数n的所有因 //子&#xff08;不包括1和自身&#xff09;之和。规定n的值不大于1000。例如&#xff0c;在主函数 //中从键盘给n输入的值为856&#xff0c;则输出为&#xff1a;sum 763。 //注意&…

嵌入式硬件篇---PID控制

文章目录 前言第一部分&#xff1a;连续PID1.比例&#xff08;Proportional&#xff0c;P&#xff09;控制2.积分&#xff08;Integral&#xff0c;I&#xff09;控制3.微分&#xff08;Derivative&#xff0c;D&#xff09;控制4.PID的工作原理5..实质6.分析7.各种PID控制器P控…

SpringBoot+Vue使用Echarts

前言 在vue项目中使用echarts&#xff0c;本次演示是使用vue2 1 前端准备 echarts官网&#xff1a; https://echarts.apache.org/zh/index.html 官网提供了基本的使用说明和大量的图表 1.1 下载echarts 执行命令 npm install echarts 直接这样执行很可能会失败&#xff0c;…

Java设计模式—观察者模式

观察者模式 目录 观察者模式1、什么是观察者模式&#xff1f;2、观察者模式优缺点及注意事项&#xff1f;3、观察者模式实现&#xff1f;4、手写线程安全的观察者模式&#xff1f; 1、什么是观察者模式&#xff1f; - 实例&#xff1a;现实生活中很多事物都是依赖存在的&#x…

如何使用 Nginx 配置反向代理?

Nginx 是一款高性能的开源 Web 服务器和反向代理服务器&#xff0c;广泛应用于负载均衡、缓存和静态文件服务。配置 Nginx 进行反向代理可以有效提高服务器性能&#xff0c;同时保护后端服务。本文将带您了解如何使用 Nginx 配置反向代理&#xff0c;并结合实际场景&#xff0c…

软件测试丨Redis 的数据同步策略以及数据一致性保证

Redis 以其键值存储的方式&#xff0c;为开发者提供了数据快速存取的能力。它不仅支持丰富的数据结构&#xff0c;如字符串、哈希、列表、集合等&#xff0c;而且提供了高效的数据同步与一致性保障机制。正因为如此&#xff0c;Redis 被广泛应用于缓存、消息队列、实时数据分析…

合唱队形(详解)

合唱队形是C的经典题目&#xff0c;在东方博宜OJ有。 题目&#xff1a; 我们能找到规律。先把上图7个数从大到小排序&#xff1a; 接着&#xff0c;我们可以定义一个copy数组&#xff0c;来从中间开始&#xff08;模拟&#xff09;&#xff1a; 题解&#xff1a; 方法一&…

【玩转全栈】----YOLO8训练自己的模型并应用

继上篇&#xff1a; 【玩转全栈】---基于YOLO8的图片、视频目标检测-CSDN博客 相信大家已经可以训练一些图片和视频了&#xff0c;接下来我将为大家介绍如何训练自己的特定模型&#xff0c;并用其进行检测 目录 准备数据 图片数据 标识数据 配置文件 运行 测试训练结果 存在的问…