Hi everyone,
I want to practice better separation of logic and data in my Unity 6.3 application, in which I use UI Toolkit.
Example: I have a set of three buttons that I need to use repeatedly. I was wondering if I can use custom controls to set up the connection of the buttons to the logic I want to execute on button click, since unfortunately, UI Toolkit cannot bind the buttons to methods via the UI Builder like uGUI can via the inspector. I already use custom controls for more complex UI elements anyway.
Now, for my custom control code to bind the button click events, it needs to know the buttons first. However, I could not figure out an elegant way to do so. I could use Q<>(), but that requires string lookup. I’d rather bind the buttons in the UI Toolkit inspector.
Here’s a piece of code to illustrate what I tried:
[UxmlElement]
public partial class MyClass : GroupBox {
[UxmlAttribute] public VisualTreeAsset someTemplate; // this works, someTemplate shows up in UI Toolkit inspector
[UxmlObjectReference("giveMeButton")] public Button giveMeButton; // this complains that Button is not a UxmlObject type
[UxmlAttribute] public Button giveMeButton; // this complains that there is no UxmlAttributeConverter
public MyClass() {
RegisterCallback<AttachToPanelEvent>(e => {
Button b = this.Q<Button>("MyButton"); // this works but I want to get rid of the string lookup
b?.RegisterCallback<ClickEvent>(evt => Debug.Log("BOOOM"));
});
}
}
That led me to looking at converters and I found Unity - Scripting API: UxmlAttributeConverter<T0> which is supposed to list the available converters. However, it does not list a converter for VisualTreeAsset, and yet I can use that, so I guess the list is incomplete.
Is what I attempted above possible? Also, does it make sense? My motives are the following:
- I do not want to bind all the click button logic in a UI manager.
- I want to have the logic for different UI blocks separate from each other.
- I do not want to create a controller class for each of my UI elements, since in cases where I need a custom control anyway, that would cause me to have a class for the custom control, a class for the data and a class for the logic, which would all have to be managed by my UI manager, which is a bit much. Hence the idea to have the logic in the custom control code.