Can you use TweenService to tween along bezier curves?

So this is the formula for a quadratic bezier curve that uses three points, and I think I can use these for a node travel system to make curves easier (for example on turns, i would only have to put down three nodes instead of laying out an entire curve):

B(t) = (1-t) BP0,P1(t) + t BP1,P2(t), 0 < t < 1

How could I use this with TweenService to tween an object’s CFrame along the calculated curve? Like, I think I can calculate the curve, but I have no idea how I’d be able to use it with TweenService.

This isnt an essential though, I just want to know if it’s possible.

1 Like

I’d recommend using lerp for this instead of tween.

Tween is usually meant for 1 end to another end without the any usual change in curve/turn, it goes in a straight line usually.

If you were to use tween for this, you could spam the tween to play but, I dont think that’ll help with performance? Lerp works perfectly fine for this, or you can just go and create your own “tween” to handle it using a module.

However to answer your question, yes its possible, no I dont recommend.

Yeah, but lerping is a curve only in terms of easing right? Usually the equivalent to a lerp is an “Out” curve for easing, and it’d look weird going from node to node because it would keep speeding up and then slowing down. Unless there’s a way to get a linear lerp

Plus, I still have no idea how to do this with Position

Tweening has the linear easing style, so it’d look much more fluent if I did that instead

The L in Lerp stands for linear. You can use CFrame:Lerp to get a CFrame in between two other CFrames (on the line that they define).

Since you can mathematically define the curve the part should move along, you really just want to make a loop that calculates the next CFrame on the curve and keeps moving the object along it.


function B(t)
    return t^2
local i = 0
local tweenLengthInSeconds = 10
local offest = part.CFrame
local con con = game:GetService("RunService").Heartbeat:Connect(function(dt)
    i = i + dt/tweenLengthInSeconds
    part.CFrame = offset **100, 0, B(math.clamp(i, 0, 1))*100)
    if i >= 1 then

Since the bezier curve is a function of t, you could try using the Tween Service to tween t from 0 to 1 and then use a connection to RenderStepped or Stepped to update the part’s CFrame using the current value of t, disconnecting once t hits 1.