r/Unity3D 20h ago

Question Easier UI Toolkit Workflow?

Anyone out there have a few methods that makes the UI Toolkit workflow easier/faster? It seems kind of clunky that to say add a button, you have to (1) add it to your doc, (2) give it a name, (3) put it in your UI script, (4) grab a reference to it using rootVisual.Q("Exact_string_name_or_kys"), (5) make a method that does whatever you need it to do, (6) subscribe onEnable to that method with .clicked or whatever you're using, and finally (7) unscubscribe onDisable. Like, nothing terribly complicated about it, but man it gets tedious over and over again. I feel like you could throw together a few methods that you basically throw in the name of your button (or any visualelement) and name of your method that does stuff you could make it way less code. Any1 out there taken the time to play around with this?

16 Upvotes

12 comments sorted by

4

u/jackbrux 20h ago

We create a custom element BindingScopeElement : VisualElement.

Then a small MonoBehaviour script to find all BindingScopeElements in the document, and assign the .dataSource to them based on the specified type in .dataSourceType. The ViewModel instances are automatically resolved from a DI framework.

1

u/Valphai 19h ago

Thats actually really clever

3

u/little-big-monkey 16h ago

I ended up treating this more as an architecture problem than doing Q() calls and callbacks everywhere.

What worked well for us was having each screen own its element references, lifecycle and event hookups, then exposing only the actions/state the rest of the UI actually needs. We also added a small layer around UI Toolkit for navigation and screen transitions, which removed quite a lot of the repetitive setup.

If you're interested, we documented the approach of our plugin here: https://littlebigmonkey.github.io/UIFlow-Docs/

2

u/jackbrux 20h ago

For your specific use case you could easily serialize the button name and event so you could do everything in the inspector:

```cs using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.UIElements;

[Serializable] public class ButtonBinding { public string buttonName; public UnityEvent onClicked;

[NonSerialized] public Button button;
[NonSerialized] public Action handler;

}

[RequireComponent(typeof(UIDocument))] public class ButtonBinder : MonoBehaviour { public List<ButtonBinding> bindings = new();

void OnEnable()
{
    var root = GetComponent<UIDocument>().rootVisualElement;

    foreach (var b in bindings)
    {
        b.button = root.Q<Button>(b.buttonName);
        if (b.button == null)
        {
            Debug.LogWarning($"No Button named '{b.buttonName}' found", this);
            continue;
        }

        var binding = b; // capture per-iteration
        b.handler = () => binding.onClicked.Invoke();
        b.button.clicked += b.handler;
    }
}

void OnDisable()
{
    foreach (var b in bindings)
        if (b.button != null && b.handler != null)
            b.button.clicked -= b.handler;
}

} ```

1

u/UpwardCourteous 20h ago

I just use a custom EditorWindow that auto-generates the UXML and USS based on a simple config, then the code side is just a dictionary that maps names to callbacks and hooks everything up in one loop.

1

u/-TheWander3r 17h ago

I wrote a source generator that goes through a uxml file and automatically writes for me a "codebehind" file that in the constructor grabs all references.

Say you have a label-status element, you press save then almost instantaneously you will find a View.LabelStatus property that you can use in code. No more possibilities of error.

It took some time to build it but now adding new UI panels has been a lot faster.

1

u/TheMaskIT 2h ago

I have seen two decent places of advice on in it 1. Use a 3 script system one is used to pull and hold references values and just kinda handle the UI nonsense. One is basically a bridge between UI script and Normal scripts (so for example making a unity event that triggers when a button it pressed) and then the last script is the actual functionality of the UI

  1. The second better advice is unless your doing a custom editor UI don't even bother with that the new UI tool kit. This advice is actually from unity themselves btw, 90% sure it is or was in the docs for the new toolkit

-5

u/a_nooblord 20h ago

This is the kind of repetitive scaffolding work that LLMs excel at.

1

u/soy1bonus Professional 19h ago

At that point, why they don't write assembly directly instead of using programming languages made for humans.

3

u/a_nooblord 18h ago

Because it was trained on human language?

1

u/soy1bonus Professional 3h ago

Assembly language was made for humans too! but is more efficient as it removes an abstraction layer.
I mean, they're already LLMs to do code with high level languages.