Graph Toolkit data driven nodes?

Maybe a package like this will allow you to do some DataDriven things without writing hundreds of PropertyDrawers. For example, displaying a Map as an Enum, etc.

I created a scriptable object that has this:

    [CreateAssetMenu(menuName = "Scriptable Objects/DialogueCharactersObject", fileName = "DialogueCharactersObject", order = 0)]
    public class DialogueCharactersObject : ScriptableObject
    {
        [System.Serializable]
        public class NameID
        {
            [SerializeField] private int uid;
            [SerializeField] private string name;

            public string Name => name;

            public int Uid => uid;
        }
        
        [SerializeField, TableList] private List<NameID> characters = new List<NameID>();

        public List<NameID> Characters => characters;
    }

Now, in order to create a Data Driven list of names, I need to go through 100 circles of hell and bad documentation.


    [Serializable]
    public class DialogueCharacterRef
    {
        [SerializeField] private int uid = -1;

        public int Uid => uid;
    }
    
    [Serializable]
    public class DialogueNode : Node
    {
        
        private const string CharacterUidOption = "CharacterUid";
        private const string TextOption = "Text";

        protected void AddInputOutputExecutionPorts(IPortDefinitionContext context)
        {
            context.AddOutputPort("Next")
                .WithDisplayName("Next")
                .Build();
            
            context.AddInputPort("In")
                .WithDisplayName("In")
                .Build();
        }
        
        protected override void OnDefinePorts(IPortDefinitionContext context)
        {
            AddInputOutputExecutionPorts(context);
            
            context.AddInputPort<DialogueCharacterRef>(CharacterUidOption)
                .WithDisplayName("Character UID")
                .WithDefaultValue(new DialogueCharacterRef());

            context.AddInputPort<string>(TextOption)
                .WithDisplayName("Text")
                .Delayed();
        }
    }

Creating a node is fairly easy, and it’s really cool. But using non-base types leads to the horror of the Property Drawer.

using System.Collections.Generic;
using System.Linq;
using Content.Scripts.Dialogues;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

namespace DialogueGraph.Editor
{
    [CustomPropertyDrawer(typeof(DialogueCharacterRef))]
    public class DialogueCharacterRefDrawer : PropertyDrawer
    {
        private const string ResourcePath = "Dialogues/DialogueCharactersObject";

        public override VisualElement CreatePropertyGUI(SerializedProperty property)
        {
            var root = new VisualElement();

            var uidProperty = property.FindPropertyRelative("uid");
            var database = Resources.Load<DialogueCharactersObject>(ResourcePath);

            if (database == null)
            {
                root.Add(new HelpBox(
                    $"Could not load '{ResourcePath}' from any Resources folder.",
                    HelpBoxMessageType.Error));
                return root;
            }

            var characters = database.Characters ?? new List<DialogueCharactersObject.NameID>();

            if (characters.Count == 0)
            {
                root.Add(new HelpBox(
                    "DialogueCharactersObject is empty.",
                    HelpBoxMessageType.Warning));
                return root;
            }

            var choices = characters.Select(c => c.Name).ToList();

            int selectedIndex = 0;
            int currentUid = uidProperty.intValue;

            int foundIndex = characters.FindIndex(c => c.Uid == currentUid);
            if (foundIndex >= 0)
                selectedIndex = foundIndex;
            else
                uidProperty.intValue = characters[0].Uid;

            var dropdown = new DropdownField(choices, selectedIndex);
            dropdown.AddToClassList("unity-base-field__aligned");

            dropdown.RegisterValueChangedCallback(evt =>
            {
                int newIndex = choices.IndexOf(evt.newValue);
                if (newIndex < 0)
                    return;

                uidProperty.intValue = characters[newIndex].Uid;
                uidProperty.serializedObject.ApplyModifiedProperties();
            });

            root.Add(dropdown);
            return root;
        }
    }
}

UnityEngine.UIElements aren’t that bad, but writing custom drivers for these things each time seems too cumbersome. I’d like proper auto-serialization like in regular editor windows, via SerializedObject.
Are there any plans to make this easier? It’s just really hard to do even the most basic things with only the basic types.