# C#: Custom properties

Source: https://tweens.gd/csharp/custom-properties/

When the catalog has no matching property, animate a callback value or supply your own getter and setter.

Examples use `using Godot;` and `using tweens.gd;` in a Node method, with targets inside the scene tree.

## Callback values

```csharp
label.Tween(new Tweens.Float
{
    From = 10,
    To = 100,
    Duration = 1,
    OnUpdate = (_, sample) => label.Text = Mathf.RoundToInt(sample).ToString(),
});
```

The label counts from 10 to 100. `OnUpdate` receives each value; the node you start on owns playback. [Callback values](https://tweens.gd/csharp/nodes/values/) lists the other value types.

## Property bindings

HealthBar.cs

```csharp
public partial class HealthBar : Node2D
{
    public float Fill { get; set; } = 1;

    static readonly Tweens.Property<HealthBar, float> Drain = new(
        bar => bar.Fill, (bar, value) => bar.Fill = value, Interpolators.Float)
        { Duration = 0.4, Ease = InOut.SmootherStep };

    public void SetHealth(float fraction) => this.Tween(Drain with { To = fraction });
}
```

1.  **Store.** Any property or field works.
2.  **Define.** A getter, a setter, and an interpolator, with the usual timing and easing.
3.  **Play.** Each call sets a new destination with `with`.

## Custom bindings

For storage independent of interpolation, derive from `TweenBinding<TTarget, TValue>`. Override `Read` and `Write`, with optional `Prepare`, `Restore`, and `Release` hooks. `PropertyBinding<TTarget, TValue>` supplies these operations from a getter and setter. The same binding works with `PropertyTween<TTarget, TValue>` for endpoints or `Tweens.Sampled<TTarget, TValue>` for a prepared keyframe curve.

`Tweens.ColorProperty<TTarget>` provides a shorter color definition: getter, setter, destination, and timing, with premultiplied OKLab supplied automatically. Its `Through` extension uses the same storage for several keys; see [keyframes](https://tweens.gd/csharp/keyframes/#storage-timing-and-sampling).

Deriving from `TweenDefinition<TTarget, TValue>` remains available when one class supplies both storage and custom interpolation. Each start works on a shallow copy, so referenced objects stay shared unless you copy them. Storage-only bindings can override `Copy` for custom mutable configuration.

Release only what your copy owns

Keep per-playback state on the playback copy, and release only resources that copy created.

[Custom definitions](https://tweens.gd/csharp/api/custom/)Every hook, its order, and failed preparation.

[Manual scheduling](https://tweens.gd/csharp/api/scheduler/)Advance tweens yourself, for plain objects and tests.
