Odd movement with linear interpolation

I have a script that can tween a part along a Bezier curve to a moving object. The problem I am having is that the movement is at irregular intervals, and starts out very fast and then slows down greatly.

you can see on this video what I am talking about. If you watch the entire thing, you can also see me scrolling through the output to show that my weight value never speeds up or slows down its increase rate. (the weight value determines how far along the curve the part should be)

here is my script:

local ts = game:GetService("TweenService")
local rs = game:GetService("RunService")

function lerp(a, b, t)
	return a + (b - a) * t
end

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

return function(part,targetpart,tweeninfo)
	local startingpoint = part.Position
	local startingrotation = part.Orientation
	local weight = Instance.new("NumberValue")

	local step = rs.Stepped:Connect(function()
		print(weight.Value)
		part.Position = quadraticBezier(weight.Value, part.Position, workspace.P2.Position, targetpart.Position)
	end)

	local tweeninfo = tweeninfo or TweenInfo.new()
	local tween = ts:Create(weight,tweeninfo,{Value = 1})
	tween:Play()
	tween.Completed:Wait()

	step:Disconnect()
end

this module script gets called in another script like this:

require(script.Parent.Tweening)(workspace.Part,workspace.me7474.HumanoidRootPart,TweenInfo.new(5,Enum.EasingStyle.Linear,Enum.EasingDirection.In))

you can also see that the easing style is linear, meaning the speed changes shouldnt happen.

I am very confused as to why this is happening, and would love assistance.

Is there a reason you’re tweening and also changing the position? Why not do everything in the step function?

I am tweening solely for the easing styles. I am using linear right now to display the odd interpolation, however once I fix that I plan on using the easing styles more.

Try creating parts at a fixed interval along the whole curve, just to see if things are evenly spaced and the path is what you expect.

They won’t be perfectly evenly spaced, because Bézier curves aren’t, but it should be as bad as your video shows.

1 Like

I will try this; I also found on the official Bezier curve page on the creator docs a solution called Arc-Length Parameterization. I have 0 clue how I could implement this as it is decently complex and I cant 100% understand it, I am wondering if you know anything on it.

link to doc with info on Arc-Length Parameterization


I added a second point, like you requested, and it revealed some odd movement. It seems to be valuing the weight of the first point more then the second. here is my revised script:

local ts = game:GetService("TweenService")
local rs = game:GetService("RunService")

function lerp(a, b, t)
	return a + (b - a) * t
end

function cubicBezier(t, p0, p1, p2, p3)
	local l1 = lerp(p0, p1, t)
	local l2 = lerp(p1, p2, t)
	local l3 = lerp(p2, p3, t)
	local l4 = lerp(l1, l2, t)
	local l5 = lerp(l2, l3, t)
	local cubic = lerp(l4, l5, t)
	return cubic
end

return function(part,targetpart,tweeninfo)
	local startingpoint = part.Position
	local startingrotation = part.Orientation
	local weight = Instance.new("NumberValue")

	local step = rs.Stepped:Connect(function()
		print(weight.Value)
		part.Position = cubicBezier(weight.Value, part.Position, workspace.P1.Position, workspace.P2.Position, targetpart.Position)
	end)

	local tweeninfo = tweeninfo or TweenInfo.new()
	local tween = ts:Create(weight,tweeninfo,{Value = 1})
	tween:Play()
	tween.Completed:Wait()

	step:Disconnect()
	local weld = Instance.new("ManualWeld")
	weld.Part0 = part
	weld.Part1 = targetpart
	weld.Parent = part
	part.Anchored = false
end

I’m not familiar with beziers but to me it looks like you’re not using startingpoint, which you should definitely be supplying to the lerp function (at least in a traditional lerp)
Did you mean to pass startingpoint to p0 instead of part.Position?

2 Likes

now that you point this out Im 90% sure it is exponentially slowing down as Im passing the part being tweened as the starting point. this would make sense as to why its slower at the end, but not why it speeds up at the start. I will report back once I fix this, if it works I will close the topic.

1 Like

this was totally the problem, its now smooth. Thanks for solving this for me!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.