> For the complete documentation index, see [llms.txt](https://kinematicsoup.gitbook.io/reactor/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kinematicsoup.gitbook.io/reactor/examples/kscurve.md).

# Curves

## Summary

*ksCurve* allows developers to use [Unity AnimationCurves](https://docs.unity3d.com/ScriptReference/AnimationCurve.html) in Reactor server scripts. This example uses *ksCurve* to animate the position of a server entity. They can be used to change any float value over time.

## Description

Add a *ksCurve* field to your server script and expose it to the editor with a `[ksEditable]` tag to create a curve field you can edit in the Unity inspector. In the inspector this field will be displayed as an *AnimationCurve* property. To use the curve, call its `Evaluate(float time)` method whenever you need a curve value.

The following script shows how you may use *ksCurve* to animate a server entity.

```c#
using KS.Reactor;
using KS.Reactor.Server;

/**
 * Animate the position of an entity relative to its rotation.
 * If another script moves the entity, then the new position will
 * be used as the new root of the animation.
 */
public class sePositionAnimation : ksServerEntityScript
{
    [ksEditable] private ksCurve m_x;
    [ksEditable] private ksCurve m_y;
    [ksEditable] private ksCurve m_z;
    private ksVector3 m_rootPosition;
    private ksVector3 m_lastPosition;

    public override void Initialize()
    {
        m_rootPosition = Transform.Position;
        m_lastPosition = Transform.Position;
        Room.OnUpdate[0] += Update;
    }

    public override void Detached()
    {
        Room.OnUpdate[0] -= Update;
    }

    public void Update()
    {
        if (m_lastPosition != Transform.Position)
        {
            m_rootPosition = Transform.Position;
        }

        ksVector3 offset = new ksVector3(
            (m_x != null) ? m_x.Evaluate((float)Time.Time) : 0.0f,
            (m_y != null) ? m_y.Evaluate((float)Time.Time) : 0.0f,
            (m_z != null) ? m_z.Evaluate((float)Time.Time) : 0.0f
        );

        offset *= Transform.Rotation;
        m_lastPosition = m_rootPosition + offset;
        Transform.Position = m_lastPosition;
    }
}
```
