Custom inspector not showing PropertyField when displayed through another class (UIElements)

60 Views Asked by At

There is a Monobehaviour class which has a property planeSettings for an scriptable object. For the scriptable object and the monobehaviours class i created custom inspectors which utilize UIElements.

The watcher is rendered correctly if i check the scriptable object itself but is missing two fields. I added a yellow line to the screenshot where they should appear. The gap is only there because i added a minHeight to the wrapping VisualElement.

Screenshot of custom inspectors

If i check the UIToolkitDebugger there are two PropertyFields listed in the VisualElement for the row but the PropertyField Details are missing. You cannot unfold the items.

UIToolkit Debugger

How to debug this further? Any thoughts for workarounds? I would like to use the monobehaviour class to bundle up several custom inspectors of different scriptable objects.

NoiseLayerPointsConfig.cs (Monobehaviour class)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NoiseLayerPointsConfig : MonoBehaviour
{

    public PlaneSettings planeSettings;
    void OnEnable()
    {
        planeSettings = Resources.Load<PlaneSettings>("Set1");
    }
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

CustomEditor_NoiseLayerPoints.cs (custom editor)

using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;

[CustomEditor(typeof(NoiseLayerPointsConfig))]
public class CustomEditor_NoiseLayerPointsInspector : Editor 
{
    private NoiseLayerPointsConfig comp;

    public override VisualElement CreateInspectorGUI()
    {
        comp = (NoiseLayerPointsConfig)target;
        
        // Create the root VisualElement
        var root = new VisualElement();
        
        // Set background color
        root.style.backgroundColor = new Color(0.0f, 0.0f, 0.0f);

        Editor planesettingsEditor = Editor.CreateEditor(comp.planeSettings);
        return new InspectorElement(planesettingsEditor);
    }
}

PlaneSettings.cs (Scriptable object)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


[CreateAssetMenu(fileName = "PlaneSettings", menuName = "ScriptableObjects/PlaneSettings", order = 1)]
public class PlaneSettings : ScriptableObject
{
    // Add your settings here. For example:
    // public float someSetting;
    public float mapWidth = 10f;
    public float mapHeight = 10f;
    public enum CoordinateMode
    {
        Center,
        LowerLeftCorner
    }
    public CoordinateMode coordinateMode = CoordinateMode.Center;
}

CustomEditor_PlaneSettings.cs (custom editor)

using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;

[CustomEditor(typeof(PlaneSettings))]
public class CustomEditor_PlaneSettingsInspector : Editor
{
 
    private PlaneSettings comp;

    public override VisualElement CreateInspectorGUI()
    {

        comp = (PlaneSettings)target;

        // Create the root VisualElement
        var root = new VisualElement();

        // Set background color
        root.style.backgroundColor = new Color(0.0f, 0.0f, 0.0f);

        root.style.paddingTop = 3f;
        root.style.paddingBottom = 3f;
        root.style.paddingLeft = 3f;
        root.style.paddingRight = 3f;



        // Create a container for the fields with a border
        var wrapperContainer = new VisualElement();
        wrapperContainer.style.borderTopWidth = wrapperContainer.style.borderRightWidth = 1;
        wrapperContainer.style.borderBottomWidth = wrapperContainer.style.borderLeftWidth = 1;
        wrapperContainer.style.backgroundColor = new Color(101f/255f, 67f/255f, 33f/255f);

        // Create a label
        var label = new Label("Plane Settings");
        label.style.unityTextAlign = TextAnchor.MiddleLeft;
        label.style.unityFontStyleAndWeight = FontStyle.Bold;
        
        wrapperContainer.Add(label);

        // Create a container for the fields with a border
        var flexContainerTileDimensions = new VisualElement();

        //flexContainerTileDimensions.style.marginTop = 5f;

        flexContainerTileDimensions.style.flexDirection = FlexDirection.Row;
        flexContainerTileDimensions.style.display = DisplayStyle.Flex;
        flexContainerTileDimensions.style.flexWrap = Wrap.Wrap;

        // Create a property field for each property you want to display
        var mapWidthField = new PropertyField(serializedComp.FindProperty("mapWidth"));
        mapWidthField.style.flexBasis = 1f;
        mapWidthField.style.flexGrow = 1f;
        mapWidthField.style.flexShrink = 0f;
        mapWidthField.style.minHeight = new StyleLength(17);

        var mapHeightField = new PropertyField(serializedComp.FindProperty("mapHeight"));
        mapHeightField.style.flexBasis = 1f;
        mapHeightField.style.flexGrow = 1f;
        mapHeightField.style.flexShrink = 0f;
        mapHeightField.style.minHeight = new StyleLength(17);

        // Add the fields to the fieldContainer VisualElement
        flexContainerTileDimensions.Add(mapWidthField);
        flexContainerTileDimensions.Add(mapHeightField);
        //flexContainerTileDimensions.style.minHeight = new StyleLength(17);

        wrapperContainer.Add(flexContainerTileDimensions);

        // Create an EnumField for the coordinateMode property
        var coordinateModeField = new EnumField((PlaneSettings.CoordinateMode)serializedComp.FindProperty("coordinateMode").enumValueIndex);
        coordinateModeField.label = "Coordinate Mode";
        coordinateModeField.labelElement.style.unityTextAlign = TextAnchor.MiddleLeft;
        coordinateModeField.RegisterValueChangedCallback(evt =>
        {
            serializedComp.FindProperty("coordinateMode").enumValueIndex = (int)(PlaneSettings.CoordinateMode)evt.newValue;
            serializedComp.ApplyModifiedProperties();
        });
        wrapperContainer.Add(coordinateModeField);




        
        root.Add(wrapperContainer);
        return root;
    }
}
1

There are 1 best solutions below

2
C4pt4inC4nn4bis On

Solved it by using FloatField instead of PropertyField in CustomEditor_PlaneSettings.cs.

Relevant part


        // Create a property field for each property you want to display
        var mapWidthField = new FloatField("mapWidth") { value = comp.mapWidth };
        mapWidthField.style.flexBasis = 1f;
        mapWidthField.style.flexGrow = 1f;
        mapWidthField.style.flexShrink = 0f;

        var mapHeightField = new FloatField("mapHeight") { value = comp.mapHeight };
        mapHeightField.style.flexBasis = 1f;
        mapHeightField.style.flexGrow = 1f;
        mapHeightField.style.flexShrink = 0f;