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:
- Bind your normalized value
- 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