Table of Contents

Introduction

Bindables is a reactive framework for managing your game state and syncing it to UI and gameplay. Easily bind to lists, dictionaries, derived state, animations, intervals, events, and even URIs

With Bindables, you declare your state using Bindable<T>, then declaratively bind that state to any Unity component—like UI text, images, animations, or prefabs. It works seamlessly across UGUI, UI Toolkit, and any other Unity objects.

In this basic example we defined Character Data on a script, and bind it to some UI:

This video demonstrates:

  • Binding string data 'Name' to the top TextMeshPro component.
  • Binding Sprite data to the Image component.
  • Binding the Health and MaxHealth float data to the slider, the slider color, and the health text.
  • BindableAnimator make the health slider, color, and text animate smoothly.

Bindables Example

Let's consider how you might implement a health bar without Bindables. Suppose you have a Player component with Health and MaxHealth data, and you want to display this data in multiple places:

  • In a text field
  • On a health slider

Doing this without Bindables is quite cumbersome and prone to error:

public class Player : MonoBehaviour
{
    public TextMeshProUGUI HealthText;
    public Slider HealthSlider;

    [SerializeField]
    private float _health;
    public float Health
    {
        get => _health;
        set
        {
            _health = value;
            UpdateHealthVisuals();
        }
    }

    [SerializeField]
    private float _maxHealth;
    public float MaxHealth
    {
        get => _maxHealth;
        set
        {
            _maxHealth = value;
            UpdateHealthVisuals();
        }
    }

    private void UpdateHealthVisuals()
    {
        HealthText.text = $"{_health} / {_maxHealth}";
        HealthSlider.value = _health / _maxHealth;
    }
}

With Bindables this becomes much more straightforward:

public class Player : MonoBehaviour
{
    public TextMeshProUGUI HealthText;
    public Slider HealthSlider;

    public Bindable<float> Health;
    public Bindable<float> MaxHealth;

    private void Start()
    {
        HealthText.BindText(Health, MaxHealth, (health, maxHealth) => $"{health} / {maxHealth}")
        HealthSlider.BindValue(Health, MaxHealth, (health, maxHealth) => health / maxHealth);
    }
}

This code is much shorter and easier to read, but it also has some other nice properties:

  • HealthText and HealthSlider will only update if the value actually changes. In the original example, we didn't check for this.
  • We don't need to remember whether to set Health and MaxHealth or _health and _maxHealth.
  • We can continue to add more bindings to Health and MaxHealth, without updating the setter or having a big UpdateHealthVisuals type of method.
  • External components can bind to Health and MaxHealth too. If desired, we can separate the data from the UI logic.
  • Health and MaxHealth will appear in the editor's inspector, where you can test different values.

But this is just the tip of the iceburg...

Features

Reactive by Design: State changes drive everything. You declare your bindings once and they update automatically.

Extension Methods: Bindables generates Bind extension methods to every Unity object (that you want). This makes easy and type-safe to bind to all built-in Unity types, 3rd party packages, and your own components. Materials, images, text, sprites, transforms, you name it.

UI Toolkit and uGUI Support: Works with both UI frameworks in the same way. Declare bindable state and bind it to UI components.

Two-Way Bindings: For input fields, sliders, dropdowns, and toggles, you can bind your state to update automatically on user input.

Advanced Bindings: Derived state, animations, time intervals, file URIs, and more.

Explore

Ready to get started? Jump into the Quick Start Guide to learn the fundamentals, or explore the API for detailed reference. If you have questions, reach out to us on Discord.