#Issue regarding PropertyDrawer in custom component editor

1 messages · Page 1 of 1 (latest)

snow rampart
#

Hello. I have two classes called IntRange and FloatRange, which serve the only purpose of checking if a given number is withing the specified range.

[Serializable]
public sealed class IntRange : INumericRange<int>
{
    const int DEFAULT_MIN = 0;
    const int DEFAULT_MAX = 10;

    public Vector2Int Limits => new(MinLimit, MaxLimit);
    [field: SerializeField, HideInInspector] public Vector2 Range { get; private set; }

    [field: SerializeField] public int MinLimit { get; private set; } = DEFAULT_MIN;
    [field: SerializeField] public int MaxLimit { get; private set; } = DEFAULT_MAX;
    [field: SerializeField] public int Min { get; private set; } = DEFAULT_MIN;
    [field: SerializeField] public int Max { get; private set; } = DEFAULT_MAX;

    public bool IsInRange(int value)
    {
        return value > Min && value < Max;
    }

    public bool IsInRangeInclusive(int value)
    {
        return value >= Min && value <= Max;
    }

    public static implicit operator bool(IntRange value) => value != null;
    public static implicit operator Vector2Int(IntRange value) => Vector2Int.FloorToInt(value.Range);
}

The other class is the same but with floats.

For flexibility, I decided to make a PropertyDrawer for each of those clases so I can modify those values smoothly.

#

Abstract class w/shared logic

public abstract class NumericRangeDrawer : PropertyDrawer
{
    const string UI_ASSET_PATH = "PyxelCosmos/Tools/NumericField/UI/UXML/NumericRangeUXML.uxml";
    protected const string RANGE_VALUE_CLASS_NAME = "rangeValueField";

    protected SerializedObject SerializedObject => Property?.serializedObject;
    protected SerializedProperty Property { get; private set; }
    protected VisualElement Root { get; private set; }

    protected SerializedProperty MinLimitProperty { get; set; }
    protected SerializedProperty MinProperty { get; set; }
    protected SerializedProperty MaxProperty { get; set; }
    protected SerializedProperty MaxLimitProperty { get; set; }
    protected SerializedProperty RangeProperty { get; set; }
    protected MinMaxSlider SliderRange { get; private set; }

    public override VisualElement CreatePropertyGUI(SerializedProperty property)
    {
        VisualTreeAsset ui = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(UI_ASSET_PATH);

        if (!ui)
            return base.CreatePropertyGUI(property);

        Property = property;
        Root = ui.CloneTree();

        SliderRange = Root.Q<MinMaxSlider>(name: "SliderRange");
        VisualElement numericRangeValuesContainer = Root.Q<VisualElement>(name: "NumericRangeValuesContainer");

        InitializeProperties();
        SliderRange.label = property.displayName;
        InitializeSliderRange();

        SetupValueFieldsContainer(numericRangeValuesContainer);

        SliderRange.RegisterValueChangedCallback(SliderValueChangedCallback);

        Root.Bind(property.serializedObject);

        return Root;
    }

    protected abstract void InitializeProperties();
    protected abstract void InitializeSliderRange();

    protected abstract void SetupValueFieldsContainer(VisualElement container);

    protected abstract void SliderValueChangedCallback(ChangeEvent<Vector2> evt);
}
#

Here comes the weird part. I made this code in a project made with Unity 2022.3.16f1, and since the tool came in handy, I decided to move it to my toolkit, which is in a project made with Unity 2022.3.21f1. Not a major version change I'd say, but apparently in the first project this was working, but in the toolkit project the property drawer doesn't work properly. It returns me the message No GUI Implemented.

My doubt is if this issue is happening due to a minimal change between those versions or because the way I'm implementing the custom inspector.

Here's how I implement the custom inspector in the toolkit project:

[CustomEditor(typeof(PyxelCosmosHelloWorld))]
public class PyxelCosmosHelloWorldInspector : Editor
{
    [SerializeField] VisualTreeAsset m_Ui;

    public override VisualElement CreateInspectorGUI()
    {
        if (!m_Ui)
            return base.CreateInspectorGUI();

        VisualElement root = m_Ui.CloneTree();

        // In UI Builder I just add a PropertyField with the bindingPath hardcoded.

        root.Bind(serializedObject);

        return root;
    }
}

And here's how I implement the custom inspector in the other project where this works:

[CustomEditor(typeof(WavesManager))]
public class WavesManagerEditor : Editor
{
    public override VisualElement CreateInspectorGUI()
    {
        VisualElement root = new();

        InspectorElement.FillDefaultInspector(root, serializedObject, this);

        return root;
    }
}

Any help is appreciated.

#

Also sorry for sending it in multiple messages, since discord won't let me send it in a single message.

#

Here's also some screenshots for context of what I'm trying to achieve

snow rampart
#

Quick update: I just checked if it was a Unity version related issue by copying the exact same files to another project of the previous version, and the issue still persists.

Therefore, I assume the issue comes from the way I'm requesting to the engine to draw the custom UI, but I still can't figure out the reason why it is not working.