Code Monkey home page Code Monkey logo

uitkeditoraid's Introduction

UITK Editor Aid

This package contains UI Toolkit elements and utilities for custom Editor interfaces in Unity.

How to install

See Install a package from a Git URL to install with the Package Manager. The git URL for this package is https://github.com/OscarAbraham/UITKEditorAid.git.

You can also download this package into your Assets folder.

Brief rundown of this package

Visit the package's API documentation for more information. Click a name to go to the relevant documentation page for usage info and some code examples:

A label that transforms into a field for editing its text. It becomes editable with a double click by default.

EditableLabel preview

A UI Toolkit element for organizing content with tabs. It has the option to support opening multiple tabs at the same time by holding shift or ctrl (or cmd in macOS) while clicking a tab. It also supports remembering the last opened tabs by assigning a unique string as a persistence key.

TabbedView preview

A UITK control for a serialized Array or List. It has many customization options.

ArrayPropertyField preview

A list of Objects similar to the components list in a GameObject's inspector. This element is typically used with a list of subassets.

ListOfInspectors preview

Element that shows a SerializedProperty's prefab override indicators, and the property's context menu. Currently, Unity only shows these things for some specific fields under specific circumstances. This element makes those features available everywhere.

Supports SerializeReference before 2022.2. Unity 2022.2 adds support for Managed References in UITK, but this element can still be useful there to go around some bugs (for example, UITK doesn't like when two classes contain fields with the same name but different type).

A customized list of Managed References

Element that prevents binding its children from higher in the hierarchy. Use this element to keep fields bound to different Objects than the rest of the UI.

Element that disables its content according to a callback. It's analogous to IMGUI's DisabledScope.

Elements for quickly adding a space along their parent's flex direction. They're analogous to IMGUI's Space and FlexibleSpace.

A Manipulator that handles treating a click as a drag when the mouse is dragged, and as a click when the mouse is clicked without moving it. It's useful for things that can be both clicked and dragged, like the headers of Components in the inspector.

Extension methods for SerializedObject that are specially useful in combination with UI Toolkit. It contains an IsEditable method that can be used in combination with the Disabler element to avoid editing objects that shouldn't be edited

Contains many extension methods for VisualElements. It has methods to manipulate only the direct children of an Element, some other methods for quickly setting multiple style properties in one go, and a method for getting the SerializedProperty that is bound to a field, among other things.

IMPORTANT: Embedding this package

If you are going to include this package inside another package or Asset Store plugin, please follow these steps to avoid collisions in projects that use this package by themselves.

uitkeditoraid's People

Contributors

oscarabraham avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

uitkeditoraid's Issues

Newer Unity versions seem to remove the need for Rebinders.

It seems recent Unity versions are a lot more efficient when binding multiple fields separately: https://github.com/needle-mirror/com.unity.ui/blob/7ae45176671504f37ebb5a5c3bacdc63cb692837/Editor/Bindings/BindingExtensions.cs#L854

I still need to take a good look there, but it seems that it'd be better to bind/rebind each element immediately instead of using the rebinder system. I'd gladly appreciate any insight that anyone has about this. Anyway, if my hunch results true, there's a decision to make:

  • We could use # if UNITY_2020_2_OR_NEWER conditionals to try to take advantage of the upgrade.
  • We could release a version 2 without the concept of Rebinders, that targets 2020.2. Personally, I'm no longer using 2019.4 because I need generic serialization; so I'm okay with that.

I'm a lot more inclined to do the second option. I'm no longer using 2019.4 because I need generics serialization; so I'm okay with ditching older versions. It just seems easier and more practical. That said, a version 2 doesn't necessarily need to remove support for older Unity versions in the manifest; things should still work there, just a lot slower. I'd be probably okay; I believe things would also be slower in earlier versions of 2020.2, anyway. That's another decision to ponder, though.

Could use a few simple examples.

I seem to be having trouble understanding how to use this library. I have the following basic setup below, which throws errors in the console whenever I reorder list elements, but when I try to use the ArrayPropertyField on my items list, it produces the same errors as before.

How am I supposed to use this library with what I have?

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

public class GenericTest : MonoBehaviour
{
    [SerializeReference] public List<Item> items = new()
    {
        new IntItem(){value = 1},
        new IntItem(){value = 2},
        new FloatItem(){value = 3.5f},
        new StringItem(){value = "Hello World"}
    };
    
    [ContextMenu("Refresh List")]
    private void RefreshParameters()
    {
        items = new()
        {
            new IntItem(){value = 1},
            new IntItem(){value = 2},
            new FloatItem(){value = 3.5f},
            new StringItem(){value = "Hello World"}
        };
    }
}

[Serializable]
public abstract class Item { }

[Serializable]
public abstract class Item<T> : Item
{
    public T value;
}

[Serializable]
public class IntItem : Item<int> { }

[Serializable]
public class FloatItem : Item<float> { }

[Serializable]
public class StringItem : Item<string> { }
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;

[CustomEditor(typeof(GenericTest))]
public class GenericTestInspector : UnityEditor.Editor
{
    private SerializedProperty itemList;
    private void OnEnable()
    {
        itemList = serializedObject.FindProperty("items");
    }

    public override VisualElement CreateInspectorGUI()
    {
        var root = new VisualElement();
        root.Add(new PropertyField(itemList));
        root.Bind(serializedObject);
        return root;
    }
}
using SCVS.Common.Editor.Extensions;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;

[CustomPropertyDrawer(typeof(Item<>), true)]
public class ItemPropertyDrawer : PropertyDrawer
{
    public override VisualElement CreatePropertyGUI(SerializedProperty property)
    {
        var root = new VisualElement();
        var value = property.FindPropertyRelative("value");

        root.Add(new PropertyField(value).BindProperty2(value));
        return root;
    }
}

Example usage/sample objects

Hey there,
Looks like you have been doing some great work here. It would definitely be helpful to folks if there were a few samples of each one that could be seen in action. I checked through the documentation, while it is quite complete, I didn't see any actual example usage. I see that you have images of each one, do you happen to a scene with a few objects in it that you used in the images somewhere? It is always helpful to have a working copy to quickly check out to see if it would work as expected.

Here is one I threw together using a few scriptableobjects if anyone needs it.

Lsit of Inspectors
// --------------------------
// --| MonoTest.cs ----------
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;

namespace instance.id
{
    [ExecuteInEditMode]
    public class MonoTest : MonoBehaviour
    {
        public List<TestSO> groupList = new List<TestSO>();

        private void OnEnable()
        {
            if (groupList.Count != 0) return;

            var gList = AssetDatabase.FindAssets($"t:{nameof(TestSO)}")
                .Select(guid => AssetDatabase.LoadAssetAtPath<TestSO>(AssetDatabase.GUIDToAssetPath(guid)))
                .ToList();

            if (gList.Count != 0) groupList = gList;
            else groupList.AddRange(new[]
            {
                ScriptableObject.CreateInstance<TestSO>(),
                ScriptableObject.CreateInstance<TestSO>(),
                ScriptableObject.CreateInstance<TestSO>()
            });

            for (int i = 0; i < groupList.Count; i++)
            {
                if (string.IsNullOrEmpty(groupList[i].name))  groupList[i].name = $"TestSO{i}";
            }
        }
    }
}
// --------------------------
// --| Place in Editor folder
// --| MonoTestEditor.cs ----
using ArteHacker.UITKEditorAid;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;

namespace instance.id.Editors
{
    [CustomEditor(typeof(MonoTest))]
    public class MonoTestEditor : Editor
    {
        private ListOfInspectors inspectorList;
        
        public override VisualElement CreateInspectorGUI()
        {
            var root = new VisualElement();
            var gList = serializedObject.FindProperty("groupList");
            inspectorList = new ListOfInspectors(gList);

            root.Add(inspectorList);
            root.Bind(serializedObject);
            root.Add(base.CreateInspectorGUI());
            return root;
        }
    }
}
using System.Collections.Generic;
using UnityEngine;

// --------------------------
// --| TestSO.cs ------------
namespace instance.id
{
    [CreateAssetMenu(menuName = "Test/TestObject", fileName = "TestObject.asset")]
    public class TestSO : ScriptableObject
    {
        public string someData;
        public float floatData;
        public List<Color> colorList = new List<Color>();

        private void OnEnable()
        {
            if (colorList.Count == 0)
                colorList.AddRange(new[]
                {
                    new Color(), new Color(), new Color()
                });
        }
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.