|
1 | | -# com.virtualmaker.bindings |
| 1 | +# VirtualMaker Bindings |
2 | 2 |
|
3 | | -[](https://discord.gg/xQgMW9ufN4) [](https://openupm.com/packages/com.virtualmaker.bindings/) [](https://openupm.com/packages/com.virtualmaker.bindings/) |
| 3 | +The VirtualMaker Bindings library provides a robust system for creating and managing properties in Unity. It allows for easy data binding between properties and UI elements, supports derived properties, and integrates seamlessly with both UGUI and UI Toolkit. |
4 | 4 |
|
5 | | -UI binding is the act of taking a data source and applying it a user interface. This is our team's package to make that as easy to do as possible. |
| 5 | +## Installation |
6 | 6 |
|
7 | | -## Installing |
| 7 | +To install the VirtualMaker Bindings library, add the following line to your `Packages/manifest.json` file in the `dependencies` section: |
8 | 8 |
|
9 | | -Requires Unity 2020.3 LTS or higher. |
| 9 | +```json |
| 10 | +"dependencies": { |
| 11 | + "com.virtualmaker.bindings": "https://github.com/virtual-maker-net/com.virtualmaker.bindings.git?path=/Bindings/Packages/com.virtualmaker.bindings#main" |
| 12 | +} |
| 13 | +``` |
10 | 14 |
|
11 | | -The recommended installation method is though the unity package manager and [OpenUPM](https://openupm.com/packages/com.virtualmaker.bindings). |
| 15 | +## Creating a `Property<T>` |
12 | 16 |
|
13 | | -### Via Unity Package Manager and OpenUPM |
| 17 | +To create a property, simply instantiate the `Property<T>` class with the desired type. Properties can be serialized to appear in the editor. |
14 | 18 |
|
15 | | -- Open your Unity project settings |
16 | | -- Select the `Package Manager` |
17 | | - |
18 | | -- Add the OpenUPM package registry: |
19 | | - - Name: `OpenUPM` |
20 | | - - URL: `https://package.openupm.com` |
21 | | - - Scope(s): |
22 | | - - `com.virtualmaker` |
23 | | -- Open the Unity Package Manager window |
24 | | -- Change the Registry from Unity to `My Registries` |
25 | | -- Add the `Bindings` package |
| 19 | +```cs |
| 20 | +using VirtualMaker.Bindings; |
26 | 21 |
|
27 | | -### Via Unity Package Manager and Git url |
| 22 | +public class Ex ampleComponent : MonoBehaviour |
| 23 | +{ |
| 24 | + [SerializeField] |
| 25 | + private Property<int> _intProperty = new(); |
28 | 26 |
|
29 | | -- Open your Unity Package Manager |
30 | | -- Add package from git url: `https://github.com/virtual-maker-net/com.virtualmaker.bindings.git#upm` |
| 27 | + [SerializeField] |
| 28 | + private Property<string> _stringProperty = new(); |
| 29 | +} |
| 30 | +``` |
31 | 31 |
|
32 | | -## Documentation |
| 32 | +## Binding to a Property with the `Bindings` Class |
33 | 33 |
|
34 | | -Key principles: |
35 | | - 1. Bindings should be simple and automatic. |
36 | | - 2. You should be able to view and edit all data in the editor for easy debugging. |
| 34 | +The `Bindings` class allows you to bind properties to callbacks or directly to UI elements. Here's an example of how to bind an `IntegerField` and a `TextField` to properties: |
37 | 35 |
|
38 | | -To implement UI bindings, we use three classes: |
39 | | -- `Property<T>` - Some data + a changed event. **These can be viewed and edited in the Unity editor**. |
40 | | -- `Derived<T, W>` - Transforms an IProperty<T> into an IProperty<W>. |
41 | | -- `Bindings` - a helper class which makes it easy to take data from an IProperty<T> and apply it to a UXML element, or vice versa. |
| 36 | +```cs |
| 37 | +using UnityEngine.UIElements; |
| 38 | +using VirtualMaker.Bindings; |
| 39 | + |
| 40 | +public class Example |
| 41 | +{ |
| 42 | + private Bindings _bindings; |
| 43 | + private Property<int> _intProperty = new(); |
| 44 | + private Property<string> _stringProperty = new(); |
| 45 | + |
| 46 | + public void SetupBindings(VisualElement root) |
| 47 | + { |
| 48 | + _bindings = new Bindings(root); |
| 49 | + |
| 50 | + // Invoke a callback now and whenever the property changes |
| 51 | + _bindings.Bind(_stringProperty, (value) => Debug.Log(value)); |
| 52 | + |
| 53 | + // Invoke a callback only when the property changes |
| 54 | + _bindings.BindDeferred(_intProperty, (value) => Debug.Log(value)); |
| 55 | + |
| 56 | + // Two-way bind to fields in the UI |
| 57 | + _bindings.BindField("my-integer-field", _intProperty, true); |
| 58 | + _bindings.BindField("my-text-field", _stringProperty, true); |
| 59 | + } |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +## Creating a Derived Property |
| 64 | + |
| 65 | +Derived properties allow you to create properties based on other properties. Here's an example of how to create a derived property: |
| 66 | + |
| 67 | +```cs |
| 68 | +using VirtualMaker.Bindings; |
| 69 | + |
| 70 | +public class Example |
| 71 | +{ |
| 72 | + private Property<int> _intProperty1 = new(); |
| 73 | + private Property<int> _intProperty2 = new(); |
| 74 | + private Derived<int> _sumProperty; |
| 75 | + |
| 76 | + public Example() |
| 77 | + { |
| 78 | + _sumProperty = Derived.From(_intProperty1, _intProperty2, (val1, val2) => val1 + val2); |
| 79 | + } |
| 80 | +} |
| 81 | +``` |
| 82 | + |
| 83 | +## Using UGUI and UI Toolkit Extensions |
| 84 | + |
| 85 | +The library provides extensions for both UGUI and UI Toolkit to facilitate binding properties to UI elements. |
| 86 | + |
| 87 | +### UGUI Example |
| 88 | + |
| 89 | +To use UGUI extensions, add the **BINDINGS_UGUI** define symbol to your project settings. |
| 90 | + |
| 91 | +```cs |
| 92 | +using UnityEngine; |
| 93 | +using TMPro; |
| 94 | +using VirtualMaker.Bindings; |
| 95 | + |
| 96 | +public class UGUIExample : MonoBehaviour |
| 97 | +{ |
| 98 | + [SerializeField] |
| 99 | + private TMP_Text text; |
| 100 | + |
| 101 | + [SerializeField] |
| 102 | + private Property<string> _textProperty = new(); |
| 103 | + |
| 104 | + private Bindings _bindings = new(); |
| 105 | + |
| 106 | + void Start() |
| 107 | + { |
| 108 | + bindings.BindText(text, _textProperty); |
| 109 | + } |
| 110 | +} |
| 111 | +``` |
| 112 | + |
| 113 | +### UI Toolkit Example |
| 114 | + |
| 115 | +To use UI Toolkit extensions, add the **BINDINGS_UI_ELEMENTS** define symbol to your project settings. |
| 116 | + |
| 117 | +```cs |
| 118 | +using UnityEngine.UIElements; |
| 119 | +using VirtualMaker.Bindings; |
| 120 | + |
| 121 | +public class UIToolkitExample |
| 122 | +{ |
| 123 | + [SerializeField] |
| 124 | + private Property<string> _textProperty = new Property<string>(); |
| 125 | + |
| 126 | + public void SetupBindings(VisualElement root) |
| 127 | + { |
| 128 | + var bindings = new Bindings(root); |
| 129 | + |
| 130 | + // Search for a text element with the name "my-label" and bind to the text property. |
| 131 | + bindings.BindText("my-label", _textProperty); |
| 132 | + |
| 133 | + // Bind to the click event of the button. You can also use On<T> to bind to any event. |
| 134 | + bindings.OnClick("my-button", () => Debug.Log("Button clicked!")); |
| 135 | + } |
| 136 | +} |
| 137 | +``` |
| 138 | + |
| 139 | +## Bindings at Edit Time |
| 140 | + |
| 141 | +You can have bindings work at edit time by adding the `[ExecuteAlways]` attribute to your MonoBehaviour class, declaring your bindings in `OnEnable`, and resetting them in `OnDisable`. |
| 142 | + |
| 143 | +### Example of Edit-Time Bindings |
| 144 | + |
| 145 | +Here's an example of a `MonoBehaviour` with edit-time bindings: |
| 146 | + |
| 147 | +```cs |
| 148 | +using UnityEngine; |
| 149 | +using UnityEngine.UIElements; |
| 150 | +using VirtualMaker.Bindings; |
| 151 | + |
| 152 | +[ExecuteAlways] |
| 153 | +public class EditTimeBindingsExample : MonoBehaviour |
| 154 | +{ |
| 155 | + [SerializeField] |
| 156 | + private Property<string> _textProperty = new Property<string>(); |
| 157 | + |
| 158 | + [SerializeField] |
| 159 | + private UIDocument _uiDocument; |
| 160 | + |
| 161 | + private Bindings _bindings; |
| 162 | + |
| 163 | + void OnEnable() |
| 164 | + { |
| 165 | + var root = _uiDocument_.rootVisualElement; |
| 166 | + _bindings = new Bindings(root); |
| 167 | + _bindings.BindText("my-label", _textProperty); |
| 168 | + } |
| 169 | + |
| 170 | + void OnDisable() |
| 171 | + { |
| 172 | + _bindings.Reset(); |
| 173 | + } |
| 174 | +} |
| 175 | +``` |
| 176 | + |
| 177 | +Now, changing the value of `_textProperty` in the editor will automatically update the bound UI element. |
0 commit comments