i really like the overall approach for the ui toolkit even though i donāt think they shouldāve done a new system completely from scratch (because itās such a massive undertaking that requires a lot of time to get to a functional state; i feel like bevy has the same nih issues).
essentially, it requires the designer to make declarative templates for ui elements and then bind that data. at its best, itās a nice no-code solution that gives granular control to designers. unfortunately, its been in development for years and is only now just barely becoming usable. this wouldnāt be a huge issue if development on the existing ui frameworks continued alongside it
so ui toolkitās data binding builds on an existing Unity concept called ScriptableObjects. these are serializable objects that are commonly used in the editor already. itās commonly used for storing definitions of things, so for example
[CreateAssetMenu(fileName = "EntityStats", menuName = "Game/Entity Stats")
public class EntityStats : ScriptableObject {
public float Health;
public float Mana;
public float Strength;
public float Agility;
}
that decorator at the top, CreateAssetMenu, does a bit of magic. this hooks into the unity editor and lets us right click in our asset window to create one of these bad girls as a file on disk. (see attached images)
this is something that could be defined on a per-entity basis to create enemy archetypes. then, when instantiating an entity, one of these could be given to it to define its stat sheet without having to bake it into the object, or make an entire prefab just to change a few numbers. itās a really nice feature that iām love
ui toolkit uses this concept for data binding. so, since we already have an entity stat sheet, lets bind it to some ui and display it. we can write the uxml directly which kind of sucks, but thankfully thereās also a graphical editor we can use
you can see at the top right of the editor, iāve bound āEntityStatsā to the top level element. in each of the labels, iāve added a binding to the specific field. and if you look at the preview, woag, it sucks but it works!! all our funny numbers are there
so thereās a couple concepts to remember:
Stats.Strength.Valuenow for the borked part
iāve been trying to display tabular data, ie. rows and columns, using ui toolkit. thereās even a premade component called MultiColumnListView which is supposed to do exactly this! it requires the designer to define columns and bind paths to each one. in the case of our EntityStats example, we could display all of entity stat archetypes in a nice table with Health, Mana, Strength, and Agility as columns! we could even add a name so we know which one it is. if we want to keep binding at design time, weāll need a new scriptable object though to hold the list of archetypes, thatās easy though
[CreateAssetMenu(fileName = "EntityArchetypes", menuName = "Game/Entity Archetypes")]
public class EntityArchetypes : ScriptableObject {
public List<EntityStats> stats;
}
after making that object and giving it a reference to the entity stats scriptable object we made before, we can start making our table to display it. donāt forget to make all the columns Stretchable
one of the more annoying parts is that for each column, we need a cell template. this is a separate uxml document describing how to display the cell
so, theoretically, unity should be iterating each item in our stats list and for each one, it goes through each column and binds a new instance of our cell template to that data and displays it. unfortunately thatās not what happens. under the hood, thereās a special itemsSource field that needs to be bound for displaying any list item. why is this different from dataSource i hear my dear reader ask?

thatās not a major problem though, and itās pretty easy to work around. we could even easily extend the capabilities of the underlying ui elements to do this binding for us automatically if we wanted.
this.SetBinding(
"itemsSource",
new DataBinding {
dataSourcePath = this.dataSourcePath
});
after extending the element and calling this line during initializing, ui toolkit should handle binding our data source path to our item source. yay! but it still doesnāt work. for some reason, it shows the type name; which is the default ToString behavior for an object. why?
thankfully ui toolkits has a debugger tool that works very roughly like a browser inspector tool
ćć¼
itās correctly iterating each of the items, but itās not using the binding path we set in the editor
so itās passing the entire EntityStats object to each cell. could we then bind in the cell template rather than the list? yes, but that would mean having a separate cell template for each cell column
