# Custom Curve

Here's a sample implementation of a [Sawtooth wave](https://en.wikipedia.org/wiki/Sawtooth_wave).

## Curve Definition

{% code fullWidth="true" %}

```cs
using System;
using FXEngine.ShakeFX;
using FXEngine.ShakeFX.Curves;
using UnityEngine;

// Sawtooth wave https://en.wikipedia.org/wiki/Sawtooth_wave
[Serializable]
public class SawtoothCurve : Curve
{
    private class RuntimeCurve : IRuntimeCurve
    {
        public float Frequency;
        public float Offset;

        public float Evaluate(in RuntimeCurveEvaluationContext context)
        {
            // Apply Frequency
            var x = context.ElapsedTime * Frequency + Offset;

            var fractional = x - Mathf.Floor(x);
            return fractional;
        }
    }

    // The oscillation frequency in cycles per second (Hz).
    public float Frequency = 3f;

    public override IRuntimeCurve CreateRuntimeCurve(in RuntimeCurveCreationContext context)
    {
        return new RuntimeCurve()
        {
            Frequency = Frequency,
            Offset = context.Offset,
        };
    }
}
```

{% endcode %}

## Motion Definitions

To use this curve inside a shake asset you'll need to define the motions:

```cs
using FXEngine.ShakeFX.Motions.Core;

// Single-axis position (Vector3) motion using a sawtooth wave.
[Motion("1 Axis/Sawtooth")]
[Serializable]
public class SawtoothMotion1AxisPosition : Motion1AxisPosition<SawtoothCurve>
{
    
}

// Single-axis rotation (Quaternion) motion using a sawtooth wave.
[Motion("1 Axis/Sawtooth")]
[Serializable]
public class SawtoothMotion1AxisRotation : Motion1AxisRotation<SawtoothCurve>
{
    
}

// Uniform (Vector3) motion using a sawtooth wave.
[Motion("Uniform/Sawtooth")]
[Serializable]
public class SawtoothMotionUniform : MotionUniform<SawtoothCurve>
{
    
}

// 1D (float) motion using a sawtooth wave.
[Motion("Sawtooth")]
[Serializable]
public class SawtoothMotion1D : Motion1D<SawtoothCurve>
{
    
}
```

## Result

The sawtooth motions are assignable to properties inside shake assets:

<figure><img src="/files/xsvXG1TrE3UXCWioN05O" alt="" width="375"><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://fx-engine.gitbook.io/shakefx/custom/custom-curve.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
