Custom GUI

Custom editor GUI

Databrain supports custom UI for your DataObject, made with the new Unity UIElements. You can create quite complex UIs with it which is also how we have created the node editor for the Logic and Techtree addons, for example.

Since version 1.1.0 it is now possible to also use Odin Inspector attributes to create custom editor GUI's. Read more

To create a custom UI with UIToolkit, simply override from EditorGUI in your DataObject class. See the following example:

using UnityEngine.UIElements;
#if UNITY_EDITOR
using UnityEditor.UIElements;
#endif

[DataObjectHideAllFields]
public class EnemyData : DataObject
{
    public int health;
    public float speed;
    
    #if UNITY_EDITOR
    // Override CustomGUI to create custom GUI for this DataObject
    public override VisualElement EditorGUI(SerializedObject _serializedObject, DatabrainEditorWindow _editorWindow)
    {
        // Create a root container
        var _root = new VisualElement();
        
        // Lets add a label
        var _label = new Label();
        _label.text = "Enemy Data";
        _label.style.fontSize = 14;
        
        // Add label to the root
        _root.Add(_label);
        
        // Add both properties
        var _healthProp = new PropertyField();
        _healthProp.BindProperty(_serializedObject.FindProperty(nameof(health)));
        
        var _speedProp = new PropertyField();
        _speedProp.BindProperty(_serializedObject.FindProperty(nameof(speed)));
        
        _root.Add(_healthProp);
        _root.Add(_speedProp);
        
        // Return the main container
        return _root;
    }
    #endif
}

Some notes regarding this script:

  • If you're using editor specific methods (like BindProperty), make sure to encapsulate the EditorGUI method in to the #if UNITY_EDITOR directive. The same goes for the UnityEditor namespace.

  • You usually don't want to show the default inspector when using a custom GUI. You can hide all fields by using the DataObjectHideAllFields attribute on the class

Custom runtime GUI

It is also possible to create a custom runtime GUI for a DataObject class. Simply override from RuntimeGUI in your DataObject class.

Here's a simple example:

public class TestData : DataObject
{ 
    public Vector3 position;
    public int health;
     
    public override VisualElement RuntimeGUI()
    {
        var _root = new VisualElement();
        
        // Vector3 field for our position field
        var _posProp = new Vector3Field();
        _posProp.bindingPath = "position";
        _posProp.RegisterValueChangedCallback<Vector3>(x =>
        {
            position = x.newValue;
        });

        // Int field for our health field
        var _healthProp = new IntegerField();
        _healthProp.RegisterValueChangedCallback<int>(x =>
        {
            health = x.newValue;
        });

        _root.Add(_posProp);
        _root.Add(_healthProp);

        return _root;
    }
}

You will then have to use it in a custom Monobehaviour script which adds the RuntimeGUI to a UIDocument like this:

public class RuntimeUITest : MonoBehaviour
{
    public DataLibrary data;

    [DataObjectDropdown("data")]
    public TestData testData;

    // Reference of the ui document in the scene
    public UIDocument document;


    public void Start()
    {
        // Create a new root visual element container
        var _root = new VisualElement();
        // Get the runtime GUI from the DataObject and add it to the container
        _root.Add(enemyData.RuntimeGUI());
        // Add the container to the document
        document.rootVisualElement.Add(_root);
    }
}

Add this script to an empty GameObject in the scene and make sure to assign a UIDocument to the document variable.

Last updated