> For the complete documentation index, see [llms.txt](https://postica.gitbook.io/binding-system-3/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://postica.gitbook.io/binding-system-3/overview/runtime-control.md).

# Controlling Bindings at Runtime

Pause, resume and refresh the bindings an object owns.

A binding that updates on the player loop is doing work every frame. Sometimes you want it to stop: the object is off screen, the menu is closed, the character is dead, a cutscene is running.

`BindingEngine` gives the object that owns the bindings a way to say so.

## The API

Extension methods, so they read as calls on the object itself:

```csharp
using Postica.BindingSystem;

public class Enemy : MonoBehaviour, IBindController
{
    void OnBecameInvisible() => this.PauseAllBinds();
    void OnBecameVisible()   => this.ResumeAllBinds();

    void OnRespawn()
    {
        this.UpdateAllBinds();          // force every binding to re-evaluate now
    }

    void OnHealthChanged()
    {
        this.UpdateBind("health");      // just this one, by path
        this.UpdateBind("health", "shield");   // or several
    }
}
```

<table><thead><tr><th width="330">Method</th><th>What it does</th></tr></thead><tbody><tr><td><code>UpdateAllBinds()</code></td><td>Re-evaluates every binding this object owns. Returns how many actually updated.</td></tr><tr><td><code>UpdateBind(path)</code> / <code>UpdateBind(params paths)</code></td><td>The same, for one or more specific paths.</td></tr><tr><td><code>PauseAllBinds()</code> / <code>ResumeAllBinds()</code></td><td>Stops and restarts the automatic updates.</td></tr><tr><td><code>PauseBind(path)</code> / <code>ResumeBind(path)</code></td><td>The same, per path. Both take a <code>params</code> array too.</td></tr><tr><td><code>ClearAllBinds()</code></td><td>Removes this object's bindings from the engine entirely.</td></tr></tbody></table>

The static forms are there when the object is not `this`:

```csharp
BindingEngine.PauseAllBinds(someOtherObject);
BindingEngine.UpdateBind(someOtherObject, "health");
```

## What counts as "the bindings this object owns"

The engine tracks bindings by the object on **either end**: the object the binding is attached to, and the object it uses as a source. Both can control it. That is usually what you want, because "pause everything reading from me" is as useful as "pause everything on me".

Registration does not depend on the update flags, so **every** proxy binding is reachable from these methods, including one with no [update point](/binding-system-3/overview/modes-and-updates.md) at all. `UpdateAllBinds` and `UpdateBind` will run it.

Pausing and resuming are the ones that need scheduled work to act on: they apply to proxy bindings with an update point, and to `Bind<T>` fields with [Auto Update](/binding-system-3/overview/modes-and-updates.md#auto-update) on. A `Bind<T>` resolved lazily when your code reads it has nothing to pause, because there is no scheduled work to stop. Guard the read yourself, turn on Auto Update, or make it a proxy binding.

{% hint style="success" %}
Deliberately leaving a proxy binding with **no** update point and calling `UpdateBind` yourself is a supported pattern, and the cheapest a binding can be: it costs nothing on the frames you do not call it. See [No update point, on purpose](/binding-system-3/overview/modes-and-updates.md#no-update-point-on-purpose).
{% endhint %}

## Who is allowed

Two models, and this is the choice the [welcome screen](/binding-system-3/getting-started/welcome-screen.md) asks about.

{% tabs %}
{% tab title="IBindController only (default off)" %}
Only objects implementing `IBindController` are tracked:

```csharp
public class Enemy : MonoBehaviour, IBindController { }
```

`IBindController` is an empty marker interface. Implementing it costs nothing and it makes the intent explicit in the type.

Nothing is tracked for objects that do not implement it, so there is no memory cost for the rest of the project.
{% endtab %}

{% tab title="Universal Bind Control" %}
Turn on **Project Settings ▸ Binding System ▸ Optimization ▸ Universal Bind Control** and every object owning a binding becomes controllable, whether or not it implements the interface.

This is the setting to use for third party components you cannot modify. The cost is a little memory and registration time per bound object.

{% hint style="warning" %}
Changing this setting requires a play mode restart to take full effect, because registration happens as bindings come alive.
{% endhint %}
{% endtab %}
{% endtabs %}

## Patterns

### Pause a whole UI panel

```csharp
public class Panel : MonoBehaviour, IBindController
{
    void OnEnable()  => this.ResumeAllBinds();
    void OnDisable() => this.PauseAllBinds();
}
```

Cheaper than it looks: disabling the GameObject already stops most work, but a binding whose *source* is elsewhere keeps running without this.

### Refresh after a load

```csharp
void OnSaveLoaded()
{
    foreach (var controller in _allControllers)
        controller.UpdateAllBinds();
}
```

Bindings that update on a specific point would otherwise wait for that point. Forcing them means everything is consistent before the first frame after the load.

### Rate-limit a heavy binding without touching its settings

```csharp
IEnumerator SlowUpdate()
{
    while (true)
    {
        this.UpdateBind("expensivePath");
        yield return new WaitForSeconds(0.5f);
    }
}
```

Usually an [interval](/binding-system-3/overview/modes-and-updates.md#intervals) on the binding is the better answer, but this works when the rate depends on game state.

## Related pages

* [Bind Modes and Update Points](/binding-system-3/overview/modes-and-updates.md): what the engine schedules in the first place.
* [Bindings Monitor](/binding-system-3/project-tools/diagnostics/bindings-monitor.md): watching the effect of a pause live.
* [Settings](/binding-system-3/reference/settings.md#optimization): Universal Bind Control.
