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
now 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?
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.Value
so ui toolkit’s data binding builds on an existing Unity concept called ScriptableObject
s. 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