0
\$\begingroup\$

I'm trying to figure out how to use curves to ease variable values in Godot 4.

Ok, I've created a curve like this:

@export var test_curve: Curve

enter image description here

I set up my curve and... how do I use it?

I've tried this:

test_curve.sample_baked(want_to_ease_this_var_w_curve)

It does nothing at all. What is the correct way of using a curve like this in Godot 4?

\$\endgroup\$
8
  • 1
    \$\begingroup\$ How do you use the return value of this sampling function in your code? \$\endgroup\$
    – DMGregory
    Commented Nov 13, 2023 at 18:09
  • \$\begingroup\$ I'm trying to use it like this: if Input.is_action_pressed("crouch"): $Head.position.y = test_curve.sample_baked(0.64 + crouching_depth) \$\endgroup\$
    – ThetaJones
    Commented Nov 13, 2023 at 18:41
  • \$\begingroup\$ And what code varies crouching_depth over time? \$\endgroup\$
    – DMGregory
    Commented Nov 13, 2023 at 19:01
  • \$\begingroup\$ I assume that the curve length is time and the points are the values that change over time. I have no idea how long this time is, though - this is really confusing to me. When the curve time is up, it just stays at the maximum value. I've tried looking at Godot documentation, but either I don't get how to read it or there's no good answer to this question there. \$\endgroup\$
    – ThetaJones
    Commented Nov 13, 2023 at 19:21
  • \$\begingroup\$ Sorry, I just realized that I forgot to provide what you asked for in the first place. The variable code is this: @export var crouching_depth = -1 \$\endgroup\$
    – ThetaJones
    Commented Nov 13, 2023 at 20:15

1 Answer 1

2
\$\begingroup\$

I assume that the curve length is time and the points are the values that change over time. I have no idea how long this time is, though

The Curve class you asked about does not have anything to with time, let alone use time as the x-axis.

Instead, it takes an x value as input from 0 to 1, and returns the y value. You may be thinking of Bezier Curves in the AnimationEditor which look similar but do use time as the x-axis and are designed to make animations such as the crouch animation you mentioned. I'll first answer the original answer then elaborate on how to use the latter.

There also exist Curve2D and Curve3D nodes for completely separate purposes, which I won't go over here.

Curves

A Curve in Godot is like a mathematical function. It takes some X value, and returns the Y value. Notably it is only defined for x between 0 and 1. Any other input value for x won't return a value.

A Curve node that looks like curve in the original question. It has

Here I have a screenshot of a curve similar to the one in the example question. If you look at the x-axis (on the bottom) you'll see numbers from 0 to 1. On the y-axis you'll see 0 to 7. If you look at the highlighted point you'll see it lines up with 0.25 on the x-axis and 3.5 on the y-axis. That means if you put in 0.25 into the sample_baked method, the curve will return 3.5. If you repeatedly input 0.25 it will return 3.5 every time.

Your code appears to input some constant value (0.64 + crouching_depth). If unchanged, it will return the same output value every time you run it. What you seem to want, is to have some animation where some variable changes to follow the curve over time.

Here's an example script you can put on a Sprite2D animate its scale over time using a Curve:

@export
var curve: Curve 
var time = 0

var timer: Timer

func _ready():
    timer = Timer.new()
    add_child(timer)
    timer.start()

func _process(delta):
    if not timer.is_stopped():
        var time_passed = timer.wait_time - timer.time_left
        var time_passed_pct = time_passed / timer.wait_time
        var s = curve.sample_baked(time_passed_pct)
        scale = Vector2(s, s)

This code snippet creates a timer. While it's running, it calculates the time elapsed since the start of the timer as a percentage between 0.0 and 1.0 (time_passed_pct). If the timer is 50% done it will be 0.5.

Then I pass this value into the Curve's sample_baked. It gets me the Y value from the Curve at that point on the x-axis. If the curve was a straight line between (0,0) and (1,1), passing in 0.5 would return 0.5.

This example should vary the Sprite's size over time. (Assuming the Curve is set up in the inspector). Timers are set to repeat by default, so it'll keep following the curve repeatedly. The most important thing to note here, is the value passed into the curve's sample function increases over time.

You could theoretically use this in a crouch animation you describe, by making the Timer a oneshot and starting it when you need the animation. However you may want to consider using Bezier Curve tracks in the AnimationPlayer instead.

Bezier Curves in AnimationPlayer

It may make more sense to use Bezier Curve Tracks in the AnimationPlayer node for most Animations.

See here for a tutorial on using the AnimationPlayer.

This approach has quite a few advantages like:

  • Automatically animating using the curve over time.
  • Allowing you to Keyframe specific values for properties with one click (like position, rotation, and scale) allowing you to merely fine-tune the in between with the curves, instead of hardcoding the input values.
  • Easy to implement and test animations in-editor

To start using Bezier Curves:

  • Create an AnimationPlayer node
  • Create a new Animation from the Animation tab on the bottom.
  • With this tab open, click the key icon (keyframe) next to your property of choice in the inspector, like position.
  • When prompted check "Use Bezier Curves"
  • Keyframe some values like a start and end position
  • Go over to the Bezier Curve Editor by clicking the little button that looks like a blue curve at the bottom of the Animation tab.

A few things to note about the Bezier Curve editor:

  • You'll need to add keyframes as points for the curve, then edit them
  • Click and drag the points or handles to manipulate the curves in the editor, similarly to the Curve editor.
  • Ctrl + Scroll zooms horizontally
  • Ctrl + Alt + Scroll zooms vertically

Finally, here's a screenshot of the Bezier Curve Editor. As you can see on the top, there's the time in seconds from 0 to 1 by default. This is changed by the text input "1" next to the stopwatch icon. When you hit the play button the AnimationPlayer will animate the properties using the curves over time in-editor.

enter image description here

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .