Game Dev Cheat Sheet

Unity Easing Functions Visualiser

Unity and Godot code for every standard easing curve. Click any curve to see the code.

Easing functions control the rate of change during an animation or transition. Instead of moving at a constant speed (linear), easing lets you start slow and end fast (ease in), start fast and end slow (ease out), or combine both. They are essential for creating natural-feeling animations in games, from UI panels sliding in to characters jumping.

In Out Cubic

1.0s
transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InOutCubic);

Compare Curves

See two easing functions side by side to pick the right feel.

Common Game Patterns

Production-ready code for common animation patterns. Click any preset to see the complete implementation.

Code Reference

Complete code for every easing function across DOTween, LeanTween, AnimationCurve, raw C#, and Godot. Expand a function to see the full code for each engine.

Linear

Linear

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.Linear);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.linear);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 1f, 1f),
    new Keyframe(1f, 1f, 1f, 1f)
);
float value = curve.Evaluate(t);

Raw C#

public static float Linear(float t)
{
    return t;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_LINEAR)
tween.set_ease(Tween.EASE_IN_OUT)

Sine

In Sine

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InSine);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInSine);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(1f, 1f, 1.57f, 1.57f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInSine(float t)
{
    return 1f - Mathf.Cos(t * Mathf.PI / 2f);
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_SINE)
tween.set_ease(Tween.EASE_IN)
Out Sine

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.OutSine);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeOutSine);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 1.57f, 1.57f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseOutSine(float t)
{
    return Mathf.Sin(t * Mathf.PI / 2f);
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_SINE)
tween.set_ease(Tween.EASE_OUT)
In Out Sine

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InOutSine);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInOutSine);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.5f, 0.5f, 1.57f, 1.57f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInOutSine(float t)
{
    return -(Mathf.Cos(Mathf.PI * t) - 1f) / 2f;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_SINE)
tween.set_ease(Tween.EASE_IN_OUT)

Quad

In Quad

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InQuad);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInQuad);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(1f, 1f, 2f, 2f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInQuad(float t)
{
    return t * t;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_QUAD)
tween.set_ease(Tween.EASE_IN)
Out Quad

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.OutQuad);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeOutQuad);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 2f, 2f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseOutQuad(float t)
{
    return 1f - (1f - t) * (1f - t);
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_QUAD)
tween.set_ease(Tween.EASE_OUT)
In Out Quad

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InOutQuad);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInOutQuad);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.5f, 0.5f, 2f, 2f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInOutQuad(float t)
{
    return t < 0.5f ? 2f * t * t : 1f - Mathf.Pow(-2f * t + 2f, 2f) / 2f;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_QUAD)
tween.set_ease(Tween.EASE_IN_OUT)

Cubic

In Cubic

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InCubic);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInCubic);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(1f, 1f, 3f, 3f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInCubic(float t)
{
    return t * t * t;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_CUBIC)
tween.set_ease(Tween.EASE_IN)
Out Cubic

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.OutCubic);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeOutCubic);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 3f, 3f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseOutCubic(float t)
{
    return 1f - Mathf.Pow(1f - t, 3f);
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_CUBIC)
tween.set_ease(Tween.EASE_OUT)
In Out Cubic

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InOutCubic);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInOutCubic);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.5f, 0.5f, 3f, 3f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInOutCubic(float t)
{
    return t < 0.5f ? 4f * t * t * t : 1f - Mathf.Pow(-2f * t + 2f, 3f) / 2f;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_CUBIC)
tween.set_ease(Tween.EASE_IN_OUT)

Quart

In Quart

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InQuart);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInQuart);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(1f, 1f, 4f, 4f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInQuart(float t)
{
    return t * t * t * t;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_QUART)
tween.set_ease(Tween.EASE_IN)
Out Quart

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.OutQuart);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeOutQuart);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 4f, 4f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseOutQuart(float t)
{
    return 1f - Mathf.Pow(1f - t, 4f);
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_QUART)
tween.set_ease(Tween.EASE_OUT)
In Out Quart

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InOutQuart);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInOutQuart);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.5f, 0.5f, 4f, 4f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInOutQuart(float t)
{
    return t < 0.5f ? 8f * t * t * t * t : 1f - Mathf.Pow(-2f * t + 2f, 4f) / 2f;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_QUART)
tween.set_ease(Tween.EASE_IN_OUT)

Quint

In Quint

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InQuint);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInQuint);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(1f, 1f, 5f, 5f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInQuint(float t)
{
    return t * t * t * t * t;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_QUINT)
tween.set_ease(Tween.EASE_IN)
Out Quint

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.OutQuint);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeOutQuint);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 5f, 5f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseOutQuint(float t)
{
    return 1f - Mathf.Pow(1f - t, 5f);
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_QUINT)
tween.set_ease(Tween.EASE_OUT)
In Out Quint

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InOutQuint);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInOutQuint);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.5f, 0.5f, 5f, 5f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInOutQuint(float t)
{
    return t < 0.5f ? 16f * t * t * t * t * t : 1f - Mathf.Pow(-2f * t + 2f, 5f) / 2f;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_QUINT)
tween.set_ease(Tween.EASE_IN_OUT)

Expo

In Expo

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InExpo);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInExpo);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(1f, 1f, 6.93f, 6.93f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInExpo(float t)
{
    return t == 0f ? 0f : Mathf.Pow(2f, 10f * t - 10f);
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_EXPO)
tween.set_ease(Tween.EASE_IN)
Out Expo

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.OutExpo);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeOutExpo);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 6.93f, 6.93f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseOutExpo(float t)
{
    return t == 1f ? 1f : 1f - Mathf.Pow(2f, -10f * t);
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_EXPO)
tween.set_ease(Tween.EASE_OUT)
In Out Expo

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InOutExpo);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInOutExpo);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.5f, 0.5f, 6.93f, 6.93f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInOutExpo(float t)
{
    return t == 0f ? 0f : t == 1f ? 1f : t < 0.5f
        ? Mathf.Pow(2f, 20f * t - 10f) / 2f
        : (2f - Mathf.Pow(2f, -20f * t + 10f)) / 2f;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_EXPO)
tween.set_ease(Tween.EASE_IN_OUT)

Circ

In Circ

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InCirc);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInCirc);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.5f, 0.134f, 0.5f, 0.5f),
    new Keyframe(1f, 1f, 10f, 10f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInCirc(float t)
{
    return 1f - Mathf.Sqrt(1f - Mathf.Pow(t, 2f));
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_CIRC)
tween.set_ease(Tween.EASE_IN)
Out Circ

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.OutCirc);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeOutCirc);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 10f, 10f),
    new Keyframe(0.5f, 0.866f, 0.5f, 0.5f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseOutCirc(float t)
{
    return Mathf.Sqrt(1f - Mathf.Pow(t - 1f, 2f));
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_CIRC)
tween.set_ease(Tween.EASE_OUT)
In Out Circ

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InOutCirc);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInOutCirc);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.5f, 0.5f, 2f, 2f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInOutCirc(float t)
{
    return t < 0.5f
        ? (1f - Mathf.Sqrt(1f - Mathf.Pow(2f * t, 2f))) / 2f
        : (Mathf.Sqrt(1f - Mathf.Pow(-2f * t + 2f, 2f)) + 1f) / 2f;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_CIRC)
tween.set_ease(Tween.EASE_IN_OUT)

Back

In Back

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InBack);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInBack);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.5f, -0.088f, 0f, 0f),
    new Keyframe(1f, 1f, 4.7f, 4.7f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInBack(float t)
{
    const float c1 = 1.70158f;
    const float c3 = c1 + 1f;
    return c3 * t * t * t - c1 * t * t;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_BACK)
tween.set_ease(Tween.EASE_IN)
Out Back

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.OutBack);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeOutBack);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 4.7f, 4.7f),
    new Keyframe(0.5f, 1.088f, 0f, 0f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseOutBack(float t)
{
    const float c1 = 1.70158f;
    const float c3 = c1 + 1f;
    return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_BACK)
tween.set_ease(Tween.EASE_OUT)
In Out Back

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InOutBack);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInOutBack);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.5f, 0.5f, 4.7f, 4.7f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInOutBack(float t)
{
    const float c1 = 1.70158f;
    const float c2 = c1 * 1.525f;
    return t < 0.5f
        ? (Mathf.Pow(2f * t, 2f) * ((c2 + 1f) * 2f * t - c2)) / 2f
        : (Mathf.Pow(2f * t - 2f, 2f) * ((c2 + 1f) * (t * 2f - 2f) + c2) + 2f) / 2f;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_BACK)
tween.set_ease(Tween.EASE_IN_OUT)

Elastic

In Elastic

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InElastic);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInElastic);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.3f, 0f, 0f, 0f),
    new Keyframe(0.7f, -0.05f, 0f, 0f),
    new Keyframe(1f, 1f, 5f, 5f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInElastic(float t)
{
    const float c4 = 2f * Mathf.PI / 3f;
    return t == 0f ? 0f : t == 1f ? 1f
        : -Mathf.Pow(2f, 10f * t - 10f) * Mathf.Sin((t * 10f - 10.75f) * c4);
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_ELASTIC)
tween.set_ease(Tween.EASE_IN)
Out Elastic

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.OutElastic);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeOutElastic);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 5f, 5f),
    new Keyframe(0.3f, 1.05f, 0f, 0f),
    new Keyframe(0.7f, 1f, 0f, 0f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseOutElastic(float t)
{
    const float c4 = 2f * Mathf.PI / 3f;
    return t == 0f ? 0f : t == 1f ? 1f
        : Mathf.Pow(2f, -10f * t) * Mathf.Sin((t * 10f - 0.75f) * c4) + 1f;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_ELASTIC)
tween.set_ease(Tween.EASE_OUT)
In Out Elastic

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InOutElastic);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInOutElastic);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.35f, -0.05f, 0f, 0f),
    new Keyframe(0.5f, 0.5f, 5f, 5f),
    new Keyframe(0.65f, 1.05f, 0f, 0f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInOutElastic(float t)
{
    const float c5 = 2f * Mathf.PI / 4.5f;
    return t == 0f ? 0f : t == 1f ? 1f : t < 0.5f
        ? -(Mathf.Pow(2f, 20f * t - 10f) * Mathf.Sin((20f * t - 11.125f) * c5)) / 2f
        : Mathf.Pow(2f, -20f * t + 10f) * Mathf.Sin((20f * t - 11.125f) * c5) / 2f + 1f;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_ELASTIC)
tween.set_ease(Tween.EASE_IN_OUT)

Bounce

In Bounce

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InBounce);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInBounce);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.09f, 0.016f, 0.5f, -0.5f),
    new Keyframe(0.27f, 0.063f, 0.5f, -0.5f),
    new Keyframe(0.64f, 0.25f, 1f, -1f),
    new Keyframe(1f, 1f, 5.5f, 5.5f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInBounce(float t)
{
    return 1f - EaseOutBounce(1f - t);
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_BOUNCE)
tween.set_ease(Tween.EASE_IN)
Out Bounce

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.OutBounce);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeOutBounce);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 5.5f, 5.5f),
    new Keyframe(0.36f, 0.75f, 1f, -1f),
    new Keyframe(0.73f, 0.937f, 0.5f, -0.5f),
    new Keyframe(0.91f, 0.984f, 0.5f, -0.5f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseOutBounce(float t)
{
    const float n1 = 7.5625f;
    const float d1 = 2.75f;
    if (t < 1f / d1) return n1 * t * t;
    if (t < 2f / d1) return n1 * (t -= 1.5f / d1) * t + 0.75f;
    if (t < 2.5f / d1) return n1 * (t -= 2.25f / d1) * t + 0.9375f;
    return n1 * (t -= 2.625f / d1) * t + 0.984375f;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_BOUNCE)
tween.set_ease(Tween.EASE_OUT)
In Out Bounce

DOTween

transform.DOMove(targetPosition, 1.0f)
    .SetEase(Ease.InOutBounce);

LeanTween

LeanTween.move(gameObject, targetPosition, 1.0f)
    .setEase(LeanTweenType.easeInOutBounce);

AnimationCurve

AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 0f, 0f, 0f),
    new Keyframe(0.15f, 0.031f, 0.5f, -0.5f),
    new Keyframe(0.32f, 0.125f, 1f, -1f),
    new Keyframe(0.5f, 0.5f, 5.5f, 5.5f),
    new Keyframe(0.68f, 0.875f, 1f, -1f),
    new Keyframe(0.85f, 0.969f, 0.5f, -0.5f),
    new Keyframe(1f, 1f, 0f, 0f)
);
float value = curve.Evaluate(t);

Raw C#

public static float EaseInOutBounce(float t)
{
    return t < 0.5f
        ? (1f - EaseOutBounce(1f - 2f * t)) / 2f
        : (1f + EaseOutBounce(2f * t - 1f)) / 2f;
}

Godot

# Godot 4 Tween
var tween = create_tween()
tween.tween_property(self, "position", target_position, 1.0)
tween.set_trans(Tween.TRANS_BOUNCE)
tween.set_ease(Tween.EASE_IN_OUT)

DOTween vs LeanTween vs AnimationCurve

Four common ways to drive easing in Unity, with the practical trade-offs.

ApproachBest forTrade-offs
DOTweenMost projects, complex sequences, callbacksExternal dependency, slight learning curve
LeanTweenLightweight projects, simple tweensSmaller API, less active maintenance
AnimationCurveDesigner-tunable feel, Inspector workflowsHigher runtime cost, not portable between projects
Raw C#Maximum control, no dependenciesMore code per tween, no built-in chaining

Frequently asked questions

Which easing function should I use for UI?
Use easeOutCubic or easeOutQuad for most UI panels and menus. They feel responsive without overshooting the target. Reserve easeOutBack for tactile button presses and easeOutElastic for celebratory moments like loot reveals or achievement popups.
Is DOTween free to use?
DOTween has a free version that covers nearly all common use cases. DOTween Pro adds path tweening, visual editor support, and TextMeshPro shortcuts, and is paid. For most studios, the free version is enough.
Can I use Unity AnimationCurve instead of easing functions?
Yes. AnimationCurve gives you full visual control in the Inspector and lets non-programmers tweak feel without recompiling. The trade-off is slightly higher runtime cost than a hardcoded easing function and the curves are not portable between projects without copying. Use AnimationCurve when designers need to tune feel; use easing functions when the curve is fixed and performance matters.
What is the difference between ease in and ease out?
Ease in starts slow and ends fast (acceleration). Ease out starts fast and ends slow (deceleration). Ease in-out does both. For things arriving on screen, ease out is almost always correct because it mirrors how objects naturally settle. For things leaving, ease in feels right.
Does LeanTween or DOTween perform better?
In typical projects the difference is negligible. DOTween has a more complete API and better documentation. LeanTween is lighter on allocations in some scenarios. Pick DOTween unless you have a measured allocation problem.

Last updated: