How can I gets the label from PropertyDrawer.CreatePropertyGUI

I write an uxml and add a PropertyField with specify label name.

<?xml version="1.0" encoding="utf-8"?>
<engine:UXML
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:engine="UnityEngine.UIElements"
    xmlns:editor="UnityEditor.UIElements"
    xsi:noNamespaceSchemaLocation="../UIElementsSchema/UIElements.xsd">
  <engine:VisualElement picking-mode="Ignore">
    <editor:PropertyField label="My Custom Label"
      binding-path="anotherNameField"/>
  </engine:VisualElement>
</engine:UXML>

The field ‘anotherNameField’ has a custom PropertyDrawer:

[CustomPropertyDrawer(typeof(AnotherName), true)]
internal sealed class AnotherNameDrawer : PropertyDrawer
{
    /// <inheritdoc/>
    public override VisualElement CreatePropertyGUI(
        SerializedProperty property)
    {
        var root = new Foldout();
        root.text = property.displayName;
        return root;
    }

    /// <inheritdoc/>
    public override void OnGUI(
        Rect position, SerializedProperty property, GUIContent label)
    {
        // Where can I get the 'label' in 'CreatePropertyGUI'?
    }
}

I can not gets the label in ‘CreatePropertyGUI’ like it can obtain in ‘OnGUI’.
How can I get the actual label content in ‘CreatePropertyGUI’?

I find the ‘PropertyField’ source code from the github:

var customPropertyGUI = handler.propertyDrawer.CreatePropertyGUI(m_SerializedProperty);

It seems not pass the label string to the PropertyDrawer at all. So there is no way to gets the correct label I think?

Is there any solution here? As there is no way to access the label in the PropertyField, I can not write a custom PropertyDrawer for it with the correct label. And the ‘tooltip’ does not work too.

Is there really no one even notice this problem?

Hi,

The label is kept and maintained by the PropertyField class itself, the drawer does not have that information, as the drawer only represents the field part of the PropertyField; PropertyField.label should be available and usable; note that if the label is not specified, the PropertyField will try to take it from the SerializedProperty directly.

The PropertyDrawer is responsible to draw the label, as I remember. Look at the PropertyDrawer document, in the OnGUI it draw the label with ‘EditorGUI.PrefixLabel’.
In the source code it try to invoke ‘CreatePropertyGUI’ first:

customPropertyGUI = handler.propertyDrawer.CreatePropertyGUI(m_SerializedProperty);
if (customPropertyGUI == null) {
    customPropertyGUI = CreatePropertyIMGUIContainer();
} else {
    RegisterPropertyChangesOnCustomDrawerElement(customPropertyGUI);
}

In the ‘CreatePropertyIMGUIContainer’, it pass the label into it, but the label is not pass to ‘CreatePropertyGUI’:

private VisualElement CreatePropertyIMGUIContainer() {
    GUIContent customLabel = string.IsNullOrEmpty(label) ? null : new GUIContent(label);
    return new IMGUIContainer(() => {
        EditorGUILayout.PropertyField(serializedProperty, new GUIContent(label), true);
    });

Like at the ‘PropertyDrawer.OnGUI’ it has the ‘label’ as the last parameter:
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label);

So I think the ‘PropertyDrawer.CreatePropertyGUI’ should have the same label.
public override VisualElement CreatePropertyGUI(SerializedProperty property, GUIContent label);

Hi, sorry for not replying to your message earlier. You are right. I will flag this.

Hi, the Unity2022.2 use the UIElements to build the inspector by default. But it not for custom editor and property drawer.
So is there any plan to support label in property drawer? It make it actual useable.

Hi, after more UIElement used in engine, is there any progress on about it?

:slight_smile: They added preferredLabel for this in 2023.1. It seems it will be backported to 2022.2 because it’s in those docs too; I haven’t downloaded the latest 2022.2 update so I can’t confirm.

For older versions I use something like this:

    internal class PropertyRoot : VisualElement
    {
        public PropertyField propertyField => parent as PropertyField;

        public string preferredLabel => propertyField?.label;

        public SerializedProperty property { get; private set; }

        public PropertyRoot(Action<PropertyRoot> onCreateGUI, SerializedProperty property)
        {
            this.property = property;
            RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);

            void OnAttachToPanel(AttachToPanelEvent e)
            {
                onCreateGUI?.Invoke(this);

                this.Bind(property?.serializedObject);
                UnregisterCallback<AttachToPanelEvent>(OnAttachToPanel);
            }
        }
    }

It can be used like this:

    internal class PropertyDrawer : PropertyDrawer
    {
        public override VisualElement CreatePropertyGUI(SerializedProperty property)
        {
            return new MyPropertyRoot(root =>
            {
                // Add your GUI elements to root here.
                // You can use root.preferredLabel to get the label.
                // One limitation is that your binding paths must be absolute to work properly.
            }, property);
        }
    }
1 Like

It a good new to have this property. But I can not find it in Unity 2022.2.1f1, even the document has it.
Maybe it only work in 2023~

I really hope they do backport it as much as they can. It doesn’t break anything, it’s easy for them to add, and it’s a very important feature for parity with IMGUI.

1 Like

Hi, it has been backported and should be available in 2022.2.2f1.

2 Likes

Finally the 2022.2.2f1 is released, and the preferredLabel is work.
But, where is the tooltip? The GUIContent not only the label text, but also the tooptip.
If I give the PropertyField a tooltip, is will not display on the custom PropertyDrawer.

1 Like

Can you please find out if someone can make InspectorNameAttribute useable for any field, instead of just enums?

I’m trying to make my own and this isn’t working:

    [CustomPropertyDrawer(typeof(LabelTextAttribute))]
    public class LabelTextDrawer : PropertyDrawer
    {
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            // Get the attribute
            LabelTextAttribute labelTextAttribute = (LabelTextAttribute)fieldInfo.GetCustomAttributes(typeof(LabelTextAttribute), false)[0];

            if (labelTextAttribute != null)
            {
                // Change the label text
                label.text = labelTextAttribute.LabelText;
            }

            // Now draw the property
            EditorGUI.PropertyField(position, property, label);
        }
    }
    [AttributeUsage(AttributeTargets.Field)]
    public class LabelTextAttribute : Attribute
    {
        public string LabelText { get; private set; }

        public LabelTextAttribute(string labelText)
        {
            LabelText = labelText;
        }
    }

Usage:

[LabelText("Test")] public bool foo;

Your LabelText attribute needs to inherit from PropertyAttribute: https://docs.unity3d.com/ScriptReference/PropertyAttribute.html

Thank you for this…blame ChatGPT for getting that wrong and I didn’t catch it.

1 Like