我正在尝试实现显示通过属性添加到ObjectField的对象的属性。通过自定义编辑器,我可以,但我厌倦了为每个新类创建一个编辑器。我想通过属性。
属性代码:
[System.AttributeUsage(System.AttributeTargets.Field)]
public class DisplayPropertiesAttribute : PropertyAttribute
{
public DisplayPropertiesAttribute() { }
}
出票人代码:
[CustomPropertyDrawer(typeof(DisplayPropertiesAttribute))]
public class DisplayPropertiesDrawer : PropertyDrawer
{
private Editor editor;
private bool foldout;
/// <summary>
/// Overrides GUI drawing for the attribute
/// </summary>
/// <param name="position"><see cref="Rect"/> fields to activate validation</param>
/// <param name="property">Serializedproperty the object</param>
/// <param name="label">Displaу field label</param>
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{// Check if this is reference type property
if (property.propertyType != SerializedPropertyType.ObjectReference)
{
// If field is not reference, show error message.
var style = new GUIStyle(EditorStyles.objectField);
style.normal.textColor = Color.red;
// Display label with error message
EditorGUI.LabelField(position, label, new GUIContent($"{property.propertyType} is not a reference type"), style);
return;
}
// If there is already an editor, add a foldout icon
if (editor) { foldout = EditorGUI.Foldout(position, foldout, new GUIContent()); }
// Start blocking change checks
EditorGUI.BeginChangeCheck();
// Display a ObjectField
EditorGUI.ObjectField(position, property, label);
// If changes were made to the contents of the field,
// or the reference is empty, there is an editor,
// or the reference is there but there is no editor
if (EditorGUI.EndChangeCheck() || (property.objectReferenceValue ^ editor))
{
// Create an editor for the object pointed to by the reference, even if reference is empty
editor = Editor.CreateEditor(property.objectReferenceValue);
}
// If foldout is true and the Editor exists
if (foldout && editor)
{
// Draw the properties of an object in a frame
GUILayout.BeginVertical(EditorStyles.helpBox);
editor.OnInspectorGUI();
GUILayout.EndVertical();
}
}
}
滚动时(字段隐藏在屏幕框架后面),出现错误:System.ArgumentException: Getting control 1's position in a group with only 1 controls when doing repaint
不显示属性。而是显示空白...
显示数组仍然有一个问题,但现在我想至少摆脱这个错误。
我将错误封装在try-catch中,只是隐藏了属性,但看起来很糟糕。
// Draw the properties of an object in a frame
try
{
GUILayout.BeginVertical(EditorStyles.helpBox);
editor.OnInspectorGUI();
GUILayout.EndVertical();
}
catch (System.ArgumentException e)
{
foldout = false;
}
1条答案
按热度按时间wn9m85ua1#
您的问题是,在PropertyDrawer中,您无法使用来自
GUILayout
或EditorGUILayout
的自动布局API,而只能使用来自GUI
和EditorGUI
的绝对Rect
API,始终传入相应的起始位置和尺寸。你需要
public override float GetPropertyHeight
,它将告诉检查员根据Rect
保留绘制您的属性Rect
传递到editor
中,并在给定位置和尺寸处绘制=〉您不能简单地使用默认编辑器来实现这一点,因为它在自动布局系统中运行,而PropertyDrawers无法使用该系统。