UI Toolkit Converters for Enum to Sprite

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.

Here is my setup:

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.
image

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…

Thanks a lot!

Hi!
You can take a look at the converter’s manual page here, specifically to the group converter part.

Note that you will need to create a Sprite to StyleBackground for the converter to succeed.

Hope this helps!

Thanks for the reply!

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…

Thanks

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);
    }

No actually I only wanna be able to use it from the UI Builder (if you meant by script). Here is what I got so far and I’m probably so wrong:

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.

When is UnitSO() getting called?

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 :stuck_out_tongue:

Thanks

As indicated here, you can use a combo of InitializeOnLoadMethod and RuntimeInitializeOnLoadMethod.

:slight_smile:

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 :stuck_out_tongue:

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 :slight_smile:

The UI Builder will clone it and if you want to use it in any context outside of the UI Builder, you will also need to clone it.

Hope this helps!

1 Like