Introduction
Bindables is a powerful reactive programming framework designed for Unity developers.
Bindables lets you track your data and game state as Bindables, and then declartively bind that state to anything in Unity. It takes advantage of C# extension methods to keep your code concise and easy to read. No more update loops or complex setters. Define your bindings once, and let the state flow naturally.
What is Reactive Programming?
In reactive programming, you declare how state should flow through your game and into your UI and gameplay.
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:
HealthTextandHealthSliderwill 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
HealthandMaxHealthor_healthand_maxHealth. - We can continue to add more bindings to
HealthandMaxHealth, without updating the setter or having a bigUpdateHealthVisualstype of method. - External components can bind to
HealthandMaxHealthtoo. If desired, we can separate the data from the UI logic. HealthandMaxHealthwill appear in the editor's inspector, where you can test different values.
This is just the tip of the iceburg. With Bindables you can:
- Bind any Unity Object's properties.
- Bind your own MonoBehaviour properties.
- Bind UI Toolkit Visual Element properties.
- Instantiate Prefabs and VisualElements from
BindableListandBindableDictionary. - Create
BindableAnimatorsfor smooth animations and transitions. - Bind to file and web URIs to automatically load textures and audio clips.
- Create two-way bindings for input fields.
- Bind to
UnityEvents,EventTrigger, and Input SystemInputActions. - Bind to
Update,LateUpdate,EndOfFrame, andIntervalloops.
Ready to get started? Jump into the Docs to learn the fundamentals, or explore the API for detailed reference. If you have questions, reach out to us on Discord.