Help with scripted Curve

Hello,
I lately tried programming a Blade-Ball / Death-Ball like game. I tried using a Bezier Curve. The curve also werks perfectly fine but when i move away or to the ball, the ball speeds up or slows down. How can i fix that?

t += dt / (startPos - RootPos).Magnitude * speed
Clone.CFrame = CFrame.new(CurveModule:quadBezier(t, startPos, Vector3.new(10, 20, 10), RootPos)) --Vecotr3 is just a Place holder
local function lerp(t, a, b)
	return a + (b - a) * t
end

function module:quadBezier(t, p0, p1, p2)
	local l1 = lerp(t, p0, p1)
	local l2 = lerp(t, p1, p2)
	local quad = lerp(t, l1, l2)
	return quad
end

Apreshate all sort of help :smiley:
Thanks

1 Like

The code you are using seems to work fine in most cases, but not in this one. The whole problem derivates from t += dt / (startPos - RootPos).Magnitude * speed

(startPos - RootPos).Magnitude is just the straight line distance between start and end, not the true Bezier curve length. Since Bezier curves bend, the actual length can be longer or shorter depending on the control point, so advancing t linearly doesn’t produce a constant speed at all.

I can’t currently think of a solution for this though as I’m not that great at Bezier curves, but I hope that you at least have a clearer idea of what the problem is.

t += dt / (startPos - RootPos).Magnitude * speed

That only considers the straight-line distance from startPos to RootPos, but your Bezier curve is longer than the straight line..

a quick untested guess
local samples = 50
local points, lengths = {}, {0}
for i = 0, samples do
	points[i] = module:quadBezier(i/samples, startPos, Vector3.new(10,20,10), RootPos)
end
local totalLength = 0
for i = 1, samples do
	local seg = (points[i] - points[i-1]).Magnitude
	totalLength += seg
	lengths[i] = totalLength
end

local function tFromDistance(d)
	for i = 1, samples do
		if d <= lengths[i] then
			local r = (d - lengths[i-1]) / (lengths[i] - lengths[i-1])
			return ((i-1) + r)/samples
		end
	end
	return 1
end

local distance = 0
task.spawn(function()
	while distance <= totalLength do
		distance += speed * task.wait()
		local t = tFromDistance(distance)
		Clone.CFrame = CFrame.new(module:quadBezier(t, startPos, Vector3.new(10,20,10), RootPos))
	end
end)