Can't get runtime data binding to work

Hello Everyone.

I am trying to use the data binding system following the example from the doc here.

I created a custom VisualElement called GaugeHorizontal. It has a public Value property. I added an instance of it in a UI document using the UI Builder. Now I am trying to bind it to a property of a MonoBehaviour like this.

public class Hud : MonoBehaviour
{
  [CreateProperty]
  public float Value;

  private void OnEnable()
  {
    Debug.Log("-> Hud Enable");

    var ui           = GetComponent<UIDocument>();
    var staminaGauge = ui.rootVisualElement.Q<GaugeHorizontal>("Stamina");
    staminaGauge.SetBinding("Value",
                            new DataBinding
                            {
                              dataSource     = this,
                              dataSourcePath = PropertyPath.FromName(nameof(Value)),
                              bindingMode    = BindingMode.ToTarget
                            });
  }

This does nothing. The Value property of GaugeHorizontal is never set. I put a trace in it and it’s never called. Did I forget something?

Also, the doc say you can do the same thing by setting dataSourcePath on staminaGauge (see the doc here). Not only that does nothing, but I don’t even understand how this is supposed to work. If I set dataSourcePath like this:
staminaGauge.dataSourcePath = PropertyPath.FromName(nameof(Value));
Then how does Unity know that it should set the Value property of staminaGauge?

Can someone please explain?

Thank you very much.

From what I can see, you haven’t assigned your data to the .dataSource of the visual element.

Thank you for your reply @spiney199.

I assume setting dataSource when creating the DataBinding should do the same. I tried giving the data source directly to the visual element but it doesn’t change anything.

public class Hud : MonoBehaviour
{
  [CreateProperty]
  public float Value;

  private void OnEnable()
  {
    Debug.Log("-> Hud Enable " + Value);

    var ui           = GetComponent<UIDocument>();
    var staminaGauge = ui.rootVisualElement.Q<GaugeHorizontal>("Stamina");
    staminaGauge.dataSource = this;
    staminaGauge.SetBinding("Value",
                            new DataBinding {dataSourcePath = PropertyPath.FromName(nameof(Value)), bindingMode = BindingMode.ToTarget});
  }
}

Hmm… Have you decorated your GaugeHorizontal.Value with [CreateProperty]?

Thank you that was it. Reading the doc I thought [CreateProperty] was only for the source and not for the target. But apparently it’s for both.

1 Like