Updated: Nov 11, 2024 | at 04:30 PM
godot math
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.
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.
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:
And when I say “completely changes,” I mean it. Let’s see how different values of curve transform your animations:
Curve: 4.0
Current curve: Ease In
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:
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:
{ 1/2(2x)−curve x < 0.5 1 - 1/2(2-2x)−c x ≥ 0.5
Common values:
// Perfect for a jumping animation
var jump_height = max_height * ease(progress, -3)
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)1curve
Popular values:
// Perfect for falling with air resistance
var fall_distance = max_fall * ease(progress, 0.33)
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: xcurve
Common values:
// Great for a charging attack
var charge_power = max_power * ease(progress, 3)
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.
Assuggested by u/Major_Gonzo on Reddit, this could also be used for “movement slowed by terrain”.
For the mathematically curious: { 1/2(2x)−curve x < 0.5 1/2(1-(1-2(x-0.5))−curve) + 0.5 x ≥ 0.5
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) }
}
Here’s your cheat sheet for the curve parameter:
What You Want | Curve Value | Example Use Case |
---|---|---|
Most Natural Movement | -2 to -5 | Character jumps, UI animations |
Deceleration | 0.2 to 0.5 | Landing, falling with resistance |
Acceleration | 2 to 4 | Charging attacks, takeoff |
Bullet Time | -0.3 to -0.8 | Special effects (rarely used) |
A few things to watch out for:
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.
Share this post on: