Jason Reppeto
Home Projects About Contact
Home Projects About Contact

Data Binding System

A highly flexible and powerful data binding system made to seamlessly integrate a data container with gameplay code.

Often times different scripts or systems on an object need to share data for a variety of reasons. This means that either there needs to be a model to act as an intermediary between the data or high levels of coupling between the scripts. Since coupling makes software more brittle the larger it is, many enterprise projects prioritize using models instead of direct references. Whereas that is not necessary for smaller projects with tiny scopes.

This data binding system allows for an extremely flexible and dynamic model to be used for any data type. It has two sections to utilize this: A data container and BindableProperties.

The data container utilizes C#'s generics to allow for type validation on a Wrapper<T> object. Additionally, every piece of data has an event for when the data is changed, in case something needs to update when a value changes, such as a UI element for player health. This data can be easily held in a dictionary of <identifier, data>. This allows for easy data queries and is essential for the next step, the bindable properties.

The BindableProperty<T> class is a generic class that contains the required information for the binding. In particular, it holds a reference to the class of the object it is bound to and the identifier of the bound data. Due to it taking in a generic type, everything is properly type checked for any logical calculations. From there, the data can be easily accessed by whatever holds the BindableProperty as a variable. Additionally, it works with Unity's inspector, allowing for a dropdown to bind the identifier without needing to type anything. Here is an example in Unity using my FSM's AccelerationAction:

public BindableProperty<Transform> trans;
public BindableProperty<Vector3> acceleration;
public BindableProperty<Vector3> velocity;

public void Execute()
{
    if (Impulse)
        return;

    var orientedVector = trans.Value.rotation * acceleration.Value;
    velocity.Set(velocity.Value + orientedVector * Time.deltaTime);
}

The name.Value simply grabs the value and lets the user access it like they would any other variable. As for name.Set(T), this obviously changes the value instead of just accessing it. This means that I can easily have a single data container, in this case a Unity component, that holds whatever data I need and it can easily be binded.

Image of a Unity component

All combined together, this allows for an extremely flexible and dynamic system without any additional effort. The best part is, it is extremely easily serializable and won't break with updates. This means it should be able to slot into any solid serialization and saving system.

[Back to the Top]