Help Understanding UI Element Converters in the Builder?

I’m a little lost on trying to implement a simple “converter”- basically I have a normalized value from 0 to 1 but I need it expressed as a number from 0 to 100, and rather than create a whole new property that’s just the original value multiplied by 100, I wanted to figure out how these converters work.

Right now this is all I got, but I’m not sure how to take this and get it into something I can simply use in the UI Builder.

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class UIConverters
{
    [InitializeOnLoadMethod]
    public static void InitConverters(){
        ConverterGroups.RegisterGlobalConverter((ref float input) => Times100Test(input));
        return;

        float Times100Test(float input){
            return input * 100;
        }
    }
}

This is where I’d thought I’d be able to access it:

Any help greatly appreciated, thank you!

1 Like

Your code is on the right track. Here’s how to properly implement and use this converter

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class UIConverters
{
    [InitializeOnLoadMethod]
    public static void InitConverters()
    {
        // Register the converter with a unique name
        BindingExtensions.RegisterValueConverter(
            "normalizedToPercentage", // converter name
            (float input) => input * 100f  // conversion function
        );
    }
}

Then in UI Builder or your UXML, you can use it like this:

  1. Bind your normalized value
  2. Add the converter to the binding using ~=

Example usage in UXML:

<Label binding-text="normalizedValue~normalizedToPercentage" />

Or if you’re creating the binding in code:

label.bindingText = new BindingText("normalizedValue")
{
    converter = "normalizedToPercentage"
};

This will automatically convert your 0-1 value to 0-100 whenever it’s displayed. The converter will be applied globally, so you can reuse it anywhere in your UI.

2 Likes

Awesome thank you! Trying it out now.
Ran into an issue though where BindingExtensions.RegisterValueConverter doesn’t seem to be in my project? Am I missing a package maybe?

Hi @thisisTeo,

The issue you are having is because the converters need to match the input and output types explicitly. In your case, your data is a float and you are trying to bind against a StyleLength. There are already converters in place for this normally, but if you want to setup a different override, you will need to return a StyleLength too:

StyleLength Times100Test(float input){ ... }

The other issue you might encounter is that you are currently defining a global converter, which means it will be applied any time a float tries to bind against a StyleLength, which is probably not what you want. You most likely want to use a scoped converter, such as this:

// Create a converter group
var group = new ConverterGroup("NormalizedValue");

// Add converters to the converter group
group.AddConverter((ref float input) => Times100Test(input));

// Register the converter group
ConverterGroups.RegisterConverterGroup(group);

Using this, in the UI Builder, when entering a converter ID for To target property, you should see the NormalizedValue group.

Hope this helps!

3 Likes

Worked like a charm! I see now how this system works more and how to organize things better. I didn’t even think about how the value needed to be a StyleLength. Thanks!

1 Like