Strange problem with PropertyField

Hello ! When I try to do this…

private VisualElement GetObjectElement(UnityEngine.Object @object)
    {
        VisualElement objectElement = new VisualElement();
        SerializedObject serializedObject = new SerializedObject(@object);
        objectElement.Add(new Label(serializedObject.targetObject.name));
        SerializedProperty current = serializedObject.GetIterator();
        if (current.NextVisible(true))
            while (current.NextVisible(false))
                if (current.name != "m_Script")
                    objectElement.Add(new PropertyField(current));

        return objectElement;
    }

… property fields are empty but when I do this…

private VisualElement GetObjectElement(UnityEngine.Object @object)
    {
        VisualElement objectElement = new VisualElement();
        SerializedObject serializedObject = new SerializedObject(@object);
        objectElement.Add(new Label(serializedObject.targetObject.name));
        SerializedProperty current = serializedObject.GetIterator();
        if (current.NextVisible(true))
            while (current.NextVisible(false))
                if (current.name != "m_Script")
                {
                    PropertyField pf = new PropertyField();
                    pf.BindProperty(current);
                    objectElement.Add(pf);
                }

        return objectElement;
    }

… everything works like a charm. What’s strange is when I look for sample code, even in UnityCsReference :
https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/Inspector/InspectorElement.cs#L290

        private VisualElement CreateDefaultInspector(SerializedObject serializedObject)
        {
            if (serializedObject == null)
                return null;

            SerializedProperty property = serializedObject.GetIterator();
            if (property.NextVisible(true)) // Expand first child.
            {
                do
                {
                    var field = new PropertyField(property);
                    field.name = "PropertyField:" + property.propertyPath;

                    if (property.propertyPath == "m_Script" && serializedObject.targetObject != null)
                        field.SetEnabled(false);

                    hierarchy.Add(field);
                }
                while (property.NextVisible(false));
            }

            if (serializedObject.targetObject == null)
                AddMissingScriptLabel(serializedObject);

            AddToClassList(uIEDefaultVariantUssClassName);
            AddToClassList(uIEInspectorVariantUssClassName);

            return this;
        }

What am I missing ?

The PropertyField(SerializedProperty) constructor sets the bindingPath but does not actually Bind() the property (which, you will have guessed, is what’s happening when you instead call BindProperty()). In the case of the InspectorElement, the call to Bind() is made at a later time.

1 Like