UnityEditor:System.ArgumentException:在重绘时获取控件 1 在只有 1 个控件的组中的位置

问题描述 投票:0回答:1

我正在尝试实现显示通过属性添加到 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;
                }
unity3d custom-attributes unity-editor
1个回答
0
投票

您的问题是,在PropertyDrawer中,您不能使用

GUILayout
EditorGUILayout
的自动布局API,而只能使用
Rect
GUI
的绝对
EditorGUI
API总是传递相应的起始位置和尺寸。

你需要

  • 计算显示嵌套内容所需的总高度
  • 将此高度添加到
    public override float GetPropertyHeight
    ,这将告诉检查员根据
    Rect
    保留以绘制您的财产
  • 将根据
    Rect
    保留给副编辑器传递给
    editor
    并在给定的位置和尺寸上绘制

=> 您不能简单地使用默认编辑器来实现这一点,因为它在 PropertyDrawers 无法使用的自动布局系统中运行。

© www.soinside.com 2019 - 2024. All rights reserved.