在PropertyDrawer中,您不能使用来自GUILayout
或EditorGUILayout
的自动布局API,而只能使用来自GUI
和EditorGUI
的绝对Rect
API始终传递相应的起始位置和维度。
你需要
- 计算显示嵌套内容所需的总高度
- 将此高度添加到
public override float GetPropertyHeight
,这将告诉检查员根据Rect
保留以绘制您的财产 - 将为sub-editor保留的相应
Rect
传递到editor
中,并在给定位置和尺寸处绘制
=>您不能简单地使用默认编辑器来实现这一点,因为它在PropertyDrawers无法使用的auto-layout系统中运行。
#region UNITY_EDITOR
using System.Collections.Generic;
using System;
using UnityEditor;
using static UnityEditor.Progress;
using UnityEngine;
using Unity.VisualScripting;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Xml.Linq;
using System.IO;public class UICollector : MonoBehaviour
{public string GenerateClassName;public OperateSetting OperateSetting;public List<ComponentInfo> components = new List<ComponentInfo>();public void GenerateMainClass(){// F:\AAAAAAAAAAAG4\UnityProject\MyDoor\trunk\client_root\Assets\Scripts\Game\Runtime\Logic\Dialog\_AirShipBodayTab.csstring mainPath = $"{Application.dataPath}/Scripts/Game/Runtime/Logic/Dialog/{GenerateClassName}.cs";if (!File.Exists(mainPath)){File.Create(mainPath).Close(); }UnityEditor.AssetDatabase.Refresh();File.WriteAllText(mainPath,@"using UnityEngine;
using System;
using UnityEngine.UI;
public partial class _D_CLASSNAME : Dialog
{public override bool IsFullScreen() { return true;}public override bool NeedShowCoins(){ return false; }protected override void OnCreate(){}
}
".Replace("_D_CLASSNAME", GenerateClassName));UnityEditor.AssetDatabase.Refresh();GeneratePartClass();}private void GeneratePartClass(){string fielddata = "";string referdata = "";foreach (var item in components){if (!string.IsNullOrEmpty(item.name)&& item.component!=null){fielddata += $"private {item.component.GetType().Name} {item.name};\n";referdata += $"{item.name} = transform.Find(\"{ item.path }\").GetComponent<{item.component.GetType().Name}>();\n";}}string baseTemp = @"using System;
using UnityEngine;
using UnityEngine.UI;public partial class _D_CLASSNAME : Dialog
{FILEDLISTprotected override void InitRef(){REFERENCE}
}
";string info = "";info = baseTemp.Replace("FILEDLIST", fielddata);info = info.Replace("_D_CLASSNAME", GenerateClassName);info = info.Replace("REFERENCE", referdata);string aprtPath = $"{Application.dataPath}/Scripts/Game/Runtime/Logic/Dialog/Partial/{GenerateClassName}.cs";if (!File.Exists(aprtPath)){File.CreateText(aprtPath).Close();UnityEditor.AssetDatabase.Refresh(); }File.WriteAllText(aprtPath, info);UnityEditor.AssetDatabase.Refresh();}}[Serializable]
public class ComponentInfo
{public string name;public string path;public int index;public UnityEngine.Component component;public GameObject go;public GameObject lastObject;
}
[CustomPropertyDrawer(typeof(ComponentInfo))]
public class ComponentInfoEditor : PropertyDrawer
{private UnityEngine.Object lastObject;public override float GetPropertyHeight(SerializedProperty property, GUIContent label){return base.GetPropertyHeight(property, label) + 40;//这个总区域的高度}public override void OnGUI(Rect position, SerializedProperty property, GUIContent label){GUI.color = Color.white;float span = 220;float width = 180;var f1Rect = new Rect(position.x + span * 1, position.y, width, 20);var f2Rect = new Rect(position.x + span * 0, position.y, width, 20);var f3Rect = new Rect(position.x, position.y + 20, width, 20);var f4Rect = new Rect(position.x + span * 1, position.y + 20, width, 20);var f5Rect = new Rect(position.x + span * 2, position.y + 20, width, 20);EditorGUIUtility.labelWidth = 70;var go = property.FindPropertyRelative("go").objectReferenceValue;if (go != null){EditorGUI.PropertyField(f2Rect, property.FindPropertyRelative("go"));bool isChange = false;var lastObject = property.FindPropertyRelative("lastObject").objectReferenceValue;if (isChange == false) isChange = lastObject != go;property.FindPropertyRelative("lastObject").objectReferenceValue = go;UnityEngine.Component[] components = go.GetComponents<UnityEngine.Component>();List<string> types = new List<string>();foreach (UnityEngine.Component comp in components){types.Add(comp.GetType().Name);}int nowindex = EditorGUI.Popup(f1Rect, property.FindPropertyRelative("index").intValue, types.ToArray());if (isChange == false) isChange = property.FindPropertyRelative("index").intValue != nowindex;property.FindPropertyRelative("index").intValue = nowindex;int index = property.FindPropertyRelative("index").intValue;property.FindPropertyRelative("component").objectReferenceValue = components[index];if (isChange || string.IsNullOrEmpty(property.FindPropertyRelative("name").stringValue)){string name = "m_" + components[index].GetType().Name.Substring(0, 4) + "_" + components[index].name;property.FindPropertyRelative("name").stringValue = name;}EditorGUI.PropertyField(f3Rect, property.FindPropertyRelative("name"));EditorGUI.PropertyField(f4Rect, property.FindPropertyRelative("component"));//当前挂载位置var parent = property.serializedObject.targetObject.GetComponent<Transform>();var curgo = go.GetComponent<Transform>();types.Clear();while (curgo != parent && curgo != null){types.Add(curgo.name);curgo = curgo.parent;}string path = "";for (int i = types.Count - 1; i >= 0; i--){path += (types[i] + (i != 0 ? "/" : ""));}property.FindPropertyRelative("path").stringValue = path;EditorGUI.PropertyField(f5Rect, property.FindPropertyRelative("path"));}else{EditorGUI.PropertyField(f2Rect, property.FindPropertyRelative("go"));}}
}[Serializable]
public class OperateSetting
{
}[CustomPropertyDrawer(typeof(OperateSetting))]
public class OperateSettingAEditor : PropertyDrawer
{private Dictionary<string, ComponentInfo> keyValuePairs = new Dictionary<string, ComponentInfo>();public override float GetPropertyHeight(SerializedProperty property, GUIContent label){return base.GetPropertyHeight(property, label) + addHeight;}private float addHeight;private string repeatname;public override void OnGUI(Rect position, SerializedProperty property, GUIContent label){//UnityEditor.EditorGUILayout.Space(60);var uiCollector = property.serializedObject.targetObject.GetComponent<UICollector>();if (string.IsNullOrEmpty(uiCollector.GenerateClassName)){uiCollector.GenerateClassName = $"_D_{uiCollector.transform.name.Replace("_d_", "")}";}if (GUI.Button(new Rect(position.x, position.y, position.width, 30), "生成CSharp")){uiCollector.GenerateMainClass();}if (uiCollector.components.Count > 0){keyValuePairs.Clear();bool isRepeat = false;foreach (var item in uiCollector.components){if (!keyValuePairs.ContainsKey(item.name)){keyValuePairs.Add(item.name,item);}else{//GUI.color = Color.red; // 设置错误文本颜色为红色repeatname = item.name;isRepeat = true;break;}}if (isRepeat){GUI.Label(new Rect(position.x, position.y + 30, position.width, 40), "重复提示:" + repeatname + "字段重复", new GUIStyle());addHeight = 40;}else{addHeight = 30;}}}
}#endregion