Skip to content

Godot's Ease Function

Updated: at 04:30 PM

Godot’s ease function is both wonderfully powerful and surprisingly messy. What looks like a simple animation function actually behaves like four completely different functions depending on how you use it.

Just need to figure out the right curve value for your animation? Jump straight to the interactive playground below! Otherwise, let’s break this down step by step.

What Makes Animations Feel Natural?

Think about a ball rolling down a hill. It starts slow, picks up speed, then gradually slows down at the bottom. Or imagine jumping - you start fast, slow down at the peak, then speed up again as you fall.

Real things rarely move at constant speeds. That’s where easing comes in - it’s how we make game animations feel natural by adding this acceleration and deceleration.

How Easing Works

An ease function takes a progress value (from 0 to 1) and returns a modified value that creates more natural movement. Simple, right?

Well, Godot decided to make things interesting. Their ease function takes two parameters:

  • x: Your progress through the animation (0 to 1)
  • curve: A magic number that completely changes how the easing behaves

And when I say “completely changes,” I mean it. Let’s see how different values of curve transform your animations:

Easing Curve Visualization
0.00.00.10.10.20.20.30.30.40.40.50.50.60.60.70.70.80.80.90.91.01.0
Current curve: Ease In

Enjoy this interactive demo? I aim to build an intuition behind complex concepts through hands-on demos and clear explanations. Join other developers who want to understand the ‘why’ behind complicated mechanics!

The Four Hidden Functions

Let’s break down each type of easing you can get from this function. I’ve ordered these from most to least useful in typical game development:

1. Ease-In-Out (curve < -1): The All-Purpose Champion

Ball Animation

Using curve = -5

This is probably what you want 80% of the time. It starts slow, speeds up in the middle, then slows down at the end - perfect for most game animations.

For the mathematically curious:

\begin{cases} \frac{1}{2}(2x)^{-\text{curve}} & x < 0.5 \\ 1 - \frac{1/2}(2-2x)^{-c} & x \geq 0.5 \end{cases}

Common values:

  • -2: Gentle ease (jumping, UI movements)
  • -3: Medium ease (character movements)
  • -5: Strong ease (dramatic effects)
# Perfect for a jumping animation
var jump_height = max_height * ease(progress, -3)

2. Ease-Out (0 < curve < 1): The Brake Pedal

Ball Animation

Using curve = 0.2

Starts fast and slows to a stop. Think of a character landing from a jump or an object falling with air resistance.

For the mathematically curious:

1-(1-x)^{\frac{1}{\text{curve}}}

Popular values:

  • 0.5 (1/2): Light braking
  • 0.33 (1/3): Medium braking
  • 0.2 (1/5): Heavy braking
# Perfect for falling with air resistance
var fall_distance = max_fall * ease(progress, 0.33)

3. Ease-In (curve ≥ 1): The Launch Pad

Ball Animation

Using curve = 4

Starts slow and keeps accelerating. Great for things that build up speed, like a charging attack or a rocket launch.

For the mathematically curious:

x^{\text{curve}}

Common values:

  • 2: Light acceleration
  • 3: Medium acceleration
  • 4: Strong acceleration
# Great for a charging attack
var charge_power = max_power * ease(progress, 3)

4. Slow-Mo (-1 < curve < 0): The Weird One

Ball Animation

Using curve = -0.3

This effect is sometimes also called ease-out-in (but I think that makes it a little confusing). It’s a bit strange - fast start, slow middle, fast end. Like a bullet-time effect. You probably won’t use this much, but it’s there if you need it.

As suggested by u/Major_Gonzo on Reddit, this could also be used for “movement slowed by terrain”.

For the mathematically curious:

\begin{cases} \frac{1}{2}(2x)^{-\text{curve}} & x < 0.5 \\ \frac{1}{2}(1-(1-2(x-0.5))^{-\text{curve}}) + 0.5 & x \geq 0.5 \end{cases}

The Math Behind the Magic

Curious how this all works under the hood? Here’s Godot’s implementation:

double Math::ease(double p_x, double p_c) {
    if (p_x < 0) {
        p_x = 0;
    } else if (p_x > 1.0) {
        p_x = 1.0;
    }
    if (p_c > 0) {
        if (p_c < 1.0) {
            return 1.0 - Math::pow(1.0 - p_x, 1.0 / p_c);
        } else {
            return Math::pow(p_x, p_c);
        }
    } else if (p_c < 0) {
        //inout ease
        if (p_x < 0.5) {
            return Math::pow(p_x * 2.0, -p_c) * 0.5;
        } else {
            return (1.0 - Math::pow(1.0 - (p_x - 0.5) * 2.0, -p_c)) * 0.5 + 0.5;
        }
    } else {
        return 0; // no ease (raw)
    }
}

Quick Reference

Here’s your cheat sheet for the curve parameter:

What You WantCurve ValueExample Use Case
Most Natural Movement-2 to -5Character jumps, UI animations
Deceleration0.2 to 0.5Landing, falling with resistance
Acceleration2 to 4Charging attacks, takeoff
Bullet Time-0.3 to -0.8Special effects (rarely used)

Common Pitfalls

A few things to watch out for:

  • Don’t use curve = 0 (returns 0) or curve = 1 (no easing effect)
  • Values between -1 and 0 create that weird slow-mo effect
  • The function clamps x between 0 and 1, so don’t worry about overshooting

Wrapping Up

The ease function might seem overcomplicated at first, but its flexibility is actually pretty powerful once you get the hang of it. Start with ease-in-out (negative values) for most cases, and experiment from there.

Found this deep dive helpful? I break down complicated concepts with clear intuition and zero fluff. Subscribe below for regular explanations that make you a better developer!