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:
usingUnityEngine.UIElements;#if UNITY_EDITORusingUnityEditor.UIElements;#endif[DataObjectHideAllFields]publicclassEnemyData:DataObject{publicint health;publicfloat speed;#if UNITY_EDITOR // Override CustomGUI to create custom GUI for this DataObjectpublicoverrideVisualElementEditorGUI(SerializedObject _serializedObject,DatabrainEditorWindow _editorWindow) { // Create a root containervar _root =newVisualElement(); // Lets add a labelvar _label =newLabel();_label.text="Enemy Data";_label.style.fontSize=14; // Add label to the root_root.Add(_label); // Add both propertiesvar _healthProp =newPropertyField();_healthProp.BindProperty(_serializedObject.FindProperty(nameof(health)));var _speedProp =newPropertyField();_speedProp.BindProperty(_serializedObject.FindProperty(nameof(speed)));_root.Add(_healthProp);_root.Add(_speedProp); // Return the main containerreturn _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:
publicclassTestData:DataObject{ publicVector3 position;publicint health;publicoverrideVisualElementRuntimeGUI() {var _root =newVisualElement(); // Vector3 field for our position fieldvar _posProp =newVector3Field();_posProp.bindingPath="position";_posProp.RegisterValueChangedCallback<Vector3>(x => { position =x.newValue; }); // Int field for our health fieldvar _healthProp =newIntegerField();_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:
publicclassRuntimeUITest:MonoBehaviour{publicDataLibrary data; [DataObjectDropdown("data")]publicTestData testData; // Reference of the ui document in the scenepublicUIDocument document;publicvoidStart() { // Create a new root visual element containervar _root =newVisualElement(); // Get the runtime GUI from the DataObject and add it to the container_root.Add(enemyData.RuntimeGUI()); // Add the container to the documentdocument.rootVisualElement.Add(_root); }}
Add this script to an empty GameObject in the scene and make sure to assign a UIDocument to the document variable.