配合自定义特性或着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里如果有未定义其他类型,记得补充