Hello! I am building my game’s UI with the UI Toolkit. It’s working pretty well so far but right now I have a question concerning converters. I saw that when adding a binding I can add a converter to a variable I assign to my binding.
I want to be able to add a binding to the background -> image property where I also add a converter to convert a certain Enum to a Sprite.
My question is then where and how do I setup my converter to get it to be usable in this context? Do I have to create it in my scriptable object that i’m using as a data source? If so i’m not sure how…
I actually am on this page since I started, but I just can’t figure out where I need to create my converter method and where to register it. Even though my data source is a SO, can I register the converter anywhere? That’s where i’m confused…
If you want to be able to use the converter from UXML, you will need to register it using InitializeOnLoadMethod and/or RuntimeInitializeOnLoadMethod. Here is an example:
#if UNITY_EDITOR
[InitializeOnLoadMethod]
#else
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
#endif
public static void RegisterConverters()
{
// Create local Converters.
var group = new ConverterGroup("Value To Progress");
// Converter groups can have multiple converters. This example converts a float to both a color and a string.
group.AddConverter((ref float v) => new StyleColor(Color.Lerp(Color.red, Color.green, v)));
group.AddConverter((ref float value) =>
{
return value switch
{
>= 0 and < 1.0f/3.0f => "Danger",
>= 1.0f/3.0f and < 2.0f/3.0f => "Neutral",
_ => "Good"
};
});
// Register the converter group in InitializeOnLoadMethod to make it accessible from the UI Builder.
ConverterGroups.RegisterConverterGroup(group);
}
And here is the code in my UnitSO scriptable object:
public UnitSO()
{
var group = new ConverterGroup("UnitElementToSprite");
group.AddConverter((ref UnitElement element) => GetSpriteFromUnitElement(element));
ConverterGroups.RegisterConverterGroup(group);
}
private StyleBackground GetSpriteFromUnitElement(UnitElement element)
{
StyleBackground styleBackground = null;
switch (element)
{
case UnitElement.Fire:
styleBackground = new StyleBackground(FireSprite);
break;
case UnitElement.Frost:
styleBackground = new StyleBackground(FrostSprite);
break;
case UnitElement.Earth:
styleBackground = new StyleBackground(EarthSprite);
break;
case UnitElement.Electric:
styleBackground = new StyleBackground(ElectricSprite);
break;
default:
break;
}
return styleBackground;
}
For now it doesn’t seem to be updating the background sprite based on the data source’s UnitElement but the Image property seems to have gone back to Texture instead of Sprite.
UnitSO is my scriptable object I use for data binding on my VisualElements. Actually you are right it might not be the right place to do the registration but I thought I had to do it in a script that is actually used, but can I just create a new static class and do my registration of converter there and I would be able to use it in my binding’s converters list?
That was pretty much my beginning question as to where to create my converter pretty much
As indicated here, you can use a combo of InitializeOnLoadMethod and RuntimeInitializeOnLoadMethod.
Once they are registered, when the VisualTreeAsset is cloned, it will be able to use the converter. This flow is directed at using converters in UXML files (so, not through code directly).
Yeah the thing is i’m not cloning any tree asset in this case I literally just created my “Shop Units” and then assigned them each a UnitSO scriptable object and then since each SO has a UnitElement, i wanted to show the right image for that element for each unit pretty much.
Right now I kinda got it working but it shows all the same sprite which it shouldn’t
EDIT: Damn I got it to work that’s pretty kewl! I accidently changed the data source on my tree asset which was overwriting all my other ones with the same sprite hehe… Thanks for you replies