在PropertyDrawer中,您不能使用来自GUILayout
或EditorGUILayout
的自动布局API,而只能使用来自GUI
和EditorGUI
的绝对Rect
API始终传递相应的起始位置和维度。
你需要
- 计算显示嵌套内容所需的总高度
- 将此高度添加到
public override float GetPropertyHeight
,这将告诉检查员根据Rect
保留以绘制您的财产 - 将为sub-editor保留的相应
Rect
传递到editor
中,并在给定位置和尺寸处绘制
=>您不能简单地使用默认编辑器来实现这一点,因为它在PropertyDrawers无法使用的auto-layout系统中运行。
cs
#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.cs
string 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
{
FILEDLIST
protected 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