Last updated
Last updated
The BindingSystem 2 is a robust Unity plugin that brings generalized value binding within projects. This comprehensive guide will walk you through the plugin's features, from binding any field to the core Bind class and extending its functionality with converters, modifiers, and more.
High-Level Features:
Quick Data Binding: Instantly connect serialized values to any Unity property, even non serialized ones, directly in Unity Editor without any code manipulation.
Two Binding Approaches: Bind any compatible field for any object directly in Inspector (even to Unity's own components), or transform your scripts' fields to bindable counterparts for maximum performance.
Non-Destructive Bind: Bind any compatible field without altering its internal data and without changing its code structure.
Opt-in Design: Once changed to bindable value, you decide whether to bind the value or just use it's pure value, without having to change your code.
Intuitive Setup: The user interface is as user-friendly and non-intrusive as it gets with a searchable dropdown menu for efficient binding configuration.
Real-Time Debugging: Identify and resolve issues with Live Debug and error visualizations, gaining valuable insights into data flow during runtime.
Custom Extensibility: The system can be easily extended with new converters, modifiers, and value providers, thus adding new capabilities to the system.
Optimized Performance: The whole system architecture was built to provide high-performance operations, optimized reflection, and methods generation with virtually no memory allocations.
The main ideology for BindingSystem is loosely based on Dependency Injection paradigm with some major differences.
There are some prominent use-cases where you can use Binding System:
You can define a physics door for example, which acts as a door but reponds to physics events as well. This door has some parameters, both for setup and for controlling the door. In typical coding fashion, to control the door, you need to add it into another controller component and pass it somehow to this controller. This creates a direct dependency:
Now whenever the logic in the door needs a small change, the risk is both files need to be touched. -> With BindingSystem, the door can have all its parameters as bindable, and the values for this parameters can come from many different sources. This removes the need to have a controller component and makes the door self-contained and independent from other code. As a bonus, this also makes the door easily testable in isolation, since at runtime you can play with parameters (both manually and automatically) to adjust its behaviour, and once finished, apply the correct bindings in correct places.
In the example above, also Lever, Slider and UI Buttons may be self-contained and provide some output parameters, effectevely making them independent and unaware where they will be used, be it for opening a door, or lowering a health bar.
Sometimes there is a need to forward some data from component A to component B. To do so, you either change A and add B as its output, change B and add A as its input or create a third one which acts as a bridge between them. It seems easy at first, but what happens if you need to send from A to C, D, E, F, and more?
With Binding System, this can be avoided without altering any of the components. The important part is that A must have its output parameters as bindable. Next is just binding this parameter to an input value (be it field, property or method) of B. This way, every time there is a change in A's output parameter value, B will receive the update immediately.
With BindingSystem, you can have a list of objects having the same type but with data coming from different sources.
Sometimes there is a need to change a value using multiple controls. For example, changing a player max speed with an UI slider, input field and physical joystick. To achieve this, a special system needs to be created to handle the input and adjustments from all this sources and apply the final correct value to max speed variable.
With BindingSystem, it is enough to use a multi-bind modifier and bind all these input sources together at the max value input parameter. The rest is automatically handled by the system.
The system can be easily adapted to Scriptable Object Architecture Paradigm (SOAP) and it even enhances certain aspects of it.
Let's take for example the idea of having a dynamic palette. A typical approach would be to create components which get the color from a palette and apply that color to some graphical elements. A palette is most often stored as a Scriptable Object. Now this object needs to be provided as parameter to the aforementioned components. Here we already encouter one of the issues: a Palette hard-reference in every component, which later can translate in maintenance hell. This could be "mitigated" by accessing a global Palette, but even this approach is problematic, since it is a singleton in disguise.
Another issue is what happens if my component doesn't require a palette in that specific area? Everything becomes more complicated and hard to maintain. Here is where Binding System can make a difference. With Binding System, every component get rid of palette and just expect its color to be always available, without knowing where the value comes from.
There's more, the version 2 of Binding System allows values to be changed during edit time, this means the palette example can be used during design time, and any change to palette will automatically apply to any bound field with its update in editor option enabled.
Since the system is quite generic, there are many more applications of such a system, especially in a dynamic environment.
We've put together some helpful guides of some core features for you to get setup with our product quickly and easily.