A player drags a slider and the music gets louder. Written by hand in a world, that is a slider wired in the inspector to an UdonBehaviour, pointed at a method named by a string you typed, which does nothing at all if you spell it wrong, rename the method, or swap the behaviour for another one. Nothing tells you. The slider just moves and nothing happens.

Udon has no UnityEvents, so there is no way to subscribe to a control from code. This package polls the control instead, and hands you a delegate the compiler checks.

```csharp
using Udonite.Binding;

public class Music : UdoniteBehaviour
{
    public Slider slider;
    public AudioSource music;

    private SliderBinding volume = new SliderBinding();

    public override void Start()
    {
        volume.Watch(slider);
        volume.OnChanged += Louder;
    }

    public override void Update()
    {
        volume.Poll();
    }

    private void Louder(float value)
    {
        music.volume = value;
    }
}
```

Nothing is wired in the inspector. `Louder` is a method the compiler knows about: rename it and the build fails, which is the whole point.

## Both directions, if you want them

An [Observable](/docs/observables) is optional on top. `Bind` instead of `Watch` keeps one in step with the control both ways — the player moves the handle and the value follows, code changes the value and the handle follows:

```csharp
private Observable<float> volume = new Observable<float>(0.5f);

private SliderBinding slider = new SliderBinding();
private FillBinding meter = new FillBinding();

public override void Start()
{
    slider.Bind(volumeSlider, volume);
    meter.Bind(volumeBar, volume);      // two views of one value
}
```

Both now show the same number, and neither knows about the other.

## Seven bindings

Four watch a control a player can use, and need `Poll()` in your `Update`:

| Binding | Control |
|---|---|
| `SliderBinding` | `Slider` |
| `ToggleBinding` | `Toggle` |
| `InputBinding` | `TMP_InputField` |

Three drive something from a value, and need no polling at all:

| Binding | Drives |
|---|---|
| `TextBinding<T>` | a label's text, with optional text either side |
| `ActiveBinding` | an object shown or hidden, straight or inverted |
| `FillBinding` | an image's fill, over a range you name |

[Getting started](/docs/binding/getting-started) is the shortest path to a working control. The [reference](/docs/binding/reference) is every member and what raises it.

## What it will not do

**Buttons.** A click is an event rather than a value. A slider's position can be read at any moment; "was clicked since last frame" cannot, so there is nothing to poll. Buttons still need the inspector, and this package does not pretend otherwise.

**URL fields.** A `VRCUrlInputField` does not focus and cannot be typed into outside a real VRChat client, so there is nothing to bind. Use its `OnEndEdit` in the inspector, which is what VRChat documents.
