> 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/tutorials/smooth-values.md).

# Making a Value Follow Smoothly

Make a bound value ease and damp instead of snapping.

A bound value follows its source exactly, which is usually right and occasionally ugly. A health bar that jumps 40% in one frame reads as a glitch. A camera bound to a target inherits every jitter the target has.

Two modifiers put time between the source and the result. This tutorial uses both on the same binding so you can see the difference, and then looks at what actually stops them working, which is not the thing most people reach for first.

## What you will build

Two bars side by side, driven by the same jumping value. One snaps, one eases, one damps. Then a demonstration of the one update setting that ruins them.

<figure><img src="https://3048705056-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLUfBXR02sJ5i0MxwYbaV%2Fuploads%2FpY40G40DesX0XQrhXIsE%2FScreenshot%202026-09-26%20at%2016.08.41.png?alt=media&amp;token=5b52df3d-45a5-4b9b-9e49-1e5e45beacf5" alt=""><figcaption><p>Three bars from one source: instant, tweened, and smoothed</p></figcaption></figure>

**About 15 minutes.**

## What you need

Anything with a number that jumps. If you did [the health bar](/binding-system-3/tutorials/health-bar.md) you have one already. If not, step 1 makes one in four lines.

## 1. Get a value that jumps

Create `Jumper.cs` and put it on any GameObject:

{% code title="Jumper.cs" %}

```csharp
using UnityEngine;

public class Jumper : MonoBehaviour
{
    [Range(0f, 1f)] public float value = 0.5f;
}
```

{% endcode %}

That is the whole thing: a slider in the Inspector you can yank around while the game runs. Nothing about binding in it.

## 2. Make three bars

Create **GameObject ▸ UI ▸ Image** three times. Name them `Instant`, `Tweened` and `Smoothed`, and stack them so all three are visible at once.

For each: set **Source Image** to `UISprite`, **Image Type** to **Filled**, **Fill Method** to **Horizontal**, **Fill Origin** to **Left**.

## 3. Bind all three to the same value

For each bar, right click **Fill Amount**, choose **Enable Binding**, click the **hexagon toggle** beside the label, then drag the `Jumper` object onto the row and pick **Jumper ▸ value**.

All three now read the same number, and **UPDATE** is already ticked on each.

Press play and drag `value`. All three bars move together, instantly. That is the baseline.

## 4. Add a Tween Animation to the second bar

Select `Tweened`. Open the bind menu and, under **Add Modifier**, choose **Tween Animation**.

Set:

* **Duration** `0.4`
* **Function** `Ease Out Quad`
* **Advanced - On target change** `Adapt Animation (Unsafe)`

Press play and yank `value`. The first bar jumps; the second takes about four tenths of a second to arrive, fast at first and slowing into place.

<figure><img src="https://3048705056-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLUfBXR02sJ5i0MxwYbaV%2Fuploads%2FPDGm2b6JyXcilNgMg20Z%2FScreenshot%202026-09-26%20at%2016.02.01.png?alt=media&amp;token=f994ce40-5d93-470e-b46c-8c63d8eedf4d" alt="" width="375"><figcaption><p>The Tween Animation modifier, set to a 0.4 second ease out</p></figcaption></figure>

{% hint style="info" %}
**On target change** is the setting that matters on a bound tween, because a bound target usually moves before the tween has finished. Leave it at the default **Ignore** and try again: the bar finishes its old journey before starting the new one, which looks like lag. **Adapt Animation (Unsafe)** retargets without restarting, and is what you want for a value that keeps moving. It is labelled unsafe because the easing shape is no longer exactly the curve you picked, not because anything can go wrong.
{% endhint %}

## 5. Add a Value Smoother to the third bar

Select `Smoothed`. Under **Add Modifier**, choose **Value Smoother**.

Leave **Speed** at `8` and **Damping** at `1`.

Press play and yank `value` repeatedly, faster than the tween can keep up with. The third bar never restarts and never lags: it just chases, and it settles without overshooting.

Now set **Damping** to `0.4` while the game is running and yank again. The bar overshoots and rings before settling. Put it back to `1`, which is critical damping and the reason this modifier has no overshoot by default.

<figure><img src="https://3048705056-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLUfBXR02sJ5i0MxwYbaV%2Fuploads%2FwU6JC2RsLQ5PAUE9PpZz%2FScreenshot%202026-09-26%20at%2016.04.47.png?alt=media&amp;token=4533b289-2b00-4e31-9042-a17ec6b16d72" alt="" width="375"><figcaption><p>The Value Smoother, with Speed and Damping</p></figcaption></figure>

## 6. Break it, deliberately

Both modifiers need the binding to run often. Here is what happens when it does not.

Select `Smoothed` and open **Update Points ▸ Update On**. Beside the interval field, switch the dropdown to **Frames** and enter `6`.

Press play and yank the value. The bar no longer glides: it steps, six frames at a time, and at 60fps that is ten visible steps a second. The maths is still correct, the animation is just being sampled far too coarsely.

<figure><img src="https://3048705056-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLUfBXR02sJ5i0MxwYbaV%2Fuploads%2FGc6QLhIxyboTSoi2eEaz%2FScreenshot%202026-09-26%20at%2016.07.32.png?alt=media&amp;token=349e1f15-6dc9-42a7-a15f-13fdab8b92f8" alt="" width="563"><figcaption><p>An interval of 6 frames, turning a smooth chase into visible steps</p></figcaption></figure>

Set the interval back to `0`.

{% hint style="warning" %}
The interval is the update setting that genuinely breaks an animated modifier, and it is worth knowing because an interval is otherwise such a good idea. A number a human reads is fine at ten updates a second. A number a human *watches move* is not.
{% endhint %}

## 7. Now check the thing you were about to worry about

**Optimized Update** is on, and it has been on this whole time. It means "skip the work when the source has not changed", which sounds exactly wrong for a tween: the source stops changing the instant you let go of the slider, and that is precisely when the tween still has most of its journey left.

Try it. Yank the value and let go. The bars finish their animation.

Turn Optimized Update off and try again. No difference.

That is not luck, and the next section explains why.

## What just happened

**A modifier can declare that it is not done.** Both of these implement a small interface that says "I am dynamic". When the binding is assembled, the pipeline looks for the first dynamic modifier in the chain and splits there:

```
source value → [ cached head ] → [ dynamic tail, re-run every update ] → target
```

Everything before the split is cached against the raw source value and skipped while that value is unchanged. Everything from the dynamic modifier onward is re-evaluated on every update. The change check that Optimized Update relies on then reports new data every time, because the reader chosen for a dynamic chain always does.

So Optimized Update and an animated modifier compose correctly, and you get the cheap half of the optimization for free. There is nothing to configure and nothing to turn off.

**The interval is a different thing entirely.** Optimized Update changes *whether the update does work*. An interval changes *how often the update happens at all*. No amount of cleverness inside the pipeline can help a modifier that is only called ten times a second. See [Bind Modes and Update Points](/binding-system-3/overview/modes-and-updates.md#intervals).

**Nothing turned the update on for you.** These modifiers do not select an update point when you add them. A proxy binding with no update point ticked and a Value Smoother on it is still a binding that does nothing at all. Here it worked because **UPDATE** was already ticked from the project default.

**On a `Bind<T>` field there is no update point to tick.** The value advances when your code reads it, so a smoother on a field you read once per frame in `Update` works, and a smoother on a field you read on a button press does not: it will have advanced by however long it has been since the last read. That is the case [Auto Update](/binding-system-3/overview/modes-and-updates.md#auto-update) exists for.

**Which one to reach for.** [Tweening and Control](/binding-system-3/pipeline/tweening.md) has the full comparison, but the short version is that **Tween Animation** is for a movement with a known duration, and **Value Smoother** is for following something that keeps moving. A health bar catching up is a smoother. A panel sliding in is a tween.

## Try changing this

**Put the Value Smoother on LATE UPDATE instead.** No visible difference here, because nothing else moves the bar. Bind a smoother to something that follows an animated bone and the difference is the whole point: **UPDATE** samples the pose from last frame, **LATE UPDATE** samples the one the animator just wrote.

**Bind the Speed.** Click the hexagon toggle beside **Speed** and point it at a value in the scene. Now the responsiveness is itself a setting, and a difficulty slider or an accessibility option can drive it. Every numeric parameter on both modifiers is bindable this way.

**Stack them.** Put a Value Smoother *after* a Tween Animation on the same binding. The tween sets a target with a shape, the smoother takes the edges off. It also makes the split visible in [Live Debug](/binding-system-3/project-tools/diagnostics/live-debug.md): one row per modifier, each showing what it did.

**Set the Tween's Time scale to Unscaled and pause the game with `Time.timeScale = 0`.** The tweened bar keeps animating and the others freeze. That is the setting a pause menu needs, and the reason it is on the modifier rather than global.

## Related pages

* [Tweening and Control](/binding-system-3/pipeline/tweening.md): every setting on the motion modifiers.
* [Bind Modes and Update Points](/binding-system-3/overview/modes-and-updates.md): intervals, Optimized Update, and Auto Update.
* [Modifiers](/binding-system-3/pipeline/modifiers.md): where these sit in the pipeline.
* [Live Debug](/binding-system-3/project-tools/diagnostics/live-debug.md): watching a chain of modifiers one stage at a time.
