Smooth Lerp Issue

Hello, I want to make smooth weld rotation lerp of a lot of parts. My issue is that its not smooth. I placed task.wait() at loops to make it less laggy but now its not smooth. It can be sharpy but not too much.

How can I make it more smooth?
Maybe I can use other way to make weld rotation, but how?

function UpdateBaseMod()
	if NeckCount.Value == 1 then
		base_mod = 0.2/NeckCount.Value
		sine_mod = 0.4/NeckCount.Value
	else
		base_mod = 0.4/NeckCount.Value
		sine_mod = 0.8/NeckCount.Value
	end
end

NeckCount.Changed:Connect(function()
	S = 0
	for i, v in pairs(Segments:GetChildren()) do
		if v.Name ~= "Segment1" then
			v:Destroy()
		end
	end
	UpdateBaseMod()
	NeckAddedEvent:FireServer(Head, S, Torso, NeckCount.Value)
end)

for i, v in pairs(Character:GetDescendants()) do
	if v:IsA("BasePart") then
		v.Massless = true
	end
end

while true do task.wait()
	for i, v in pairs(Segments:GetDescendants()) do task.wait()
		if v.Name == "WeldX" then
			local angle = -Humanoid.MoveDirection.Magnitude * (base_mod + sine_mod * math.abs(math.sin(tick() * sine_speed)) )
			v.C0 = v.C0:Lerp(CFrame.Angles(-Humanoid.MoveDirection.Magnitude * (1/NeckCount.Value), 0, 0), lerp_mod)
		end
	end
end

This is part where it lerp welds:

while true do task.wait()
	for i, v in pairs(Segments:GetDescendants()) do task.wait()
		if v.Name == "WeldX" then
			local angle = -Humanoid.MoveDirection.Magnitude * (base_mod + sine_mod * math.abs(math.sin(tick() * sine_speed)) )
			v.C0 = v.C0:Lerp(CFrame.Angles(-Humanoid.MoveDirection.Magnitude * (1/NeckCount.Value), 0, 0), lerp_mod)
		end
	end
end

I’m in hurry so please help.

You could try lowering lerp_mod and making it change less to make it smoother, but this isn’t really ideal

You could also try changing the lerp from a CFrame based lerp to a lerp of just the angle number, but even at this high of a rate it shouldn’t make that much of a difference

There’s also a lot of smaller optimizations you could make, like you don’t have to :GetDescendants 60 times a second, and you don’t have to index the weld 60 times a second

Perhaps you could get a table of the welds every time the number of segments changes

Many of the things you index hundreds of times could also be saved to a variable outside the for loop, like the number of segments and humanoid move direction

Okay, so I added table that updates when number of segments changes, but now its not playing lerp.

And also how can I save move direction outside loop? And what other variable can I store behind the loop?

And I still dont know how to make it smoother without making it laggy :sad:

function UpdateBaseMod()
	if NeckCount.Value == 1 then
		base_mod = 0.2/NeckCount.Value --0.2
		sine_mod = 0.4/NeckCount.Value --0.4
	else
		base_mod = 0.4/NeckCount.Value --0.4
		sine_mod = 0.8/NeckCount.Value --0.8
	end
	
	base_mod /= NeckCount.Value
	sine_mod /= NeckCount.Value
end

local Necks = {}

NeckCount.Changed:Connect(function()
	S = 0
	
	table.clear(Necks)
	for i, v in pairs(Segments:GetDescendants()) do -- Updating table when segments changes
		if v.Name == "WeldX" then
			table.insert(Necks, v)
			print(Necks)
		end
	end
	
	for i, v in pairs(Segments:GetChildren()) do
		v:Destroy()
	end
	UpdateBaseMod()
	NeckAddedEvent:FireServer(Head, S, Torso, NeckCount.Value)
end)

while true do task.wait()
	for i, v in next, Necks do task.wait()
		local angle = -Humanoid.MoveDirection.Magnitude * (base_mod + sine_mod * math.abs(math.sin(tick() * sine_speed)) )
		v.C0 = v.C0:Lerp(CFrame.Angles(angle, 0, 0), lerp_mod)
	end
end

You can move basically everything out

while true do task.wait()
    local angle = -Humanoid.MoveDirection.Magnitude * (base_mod + sine_mod * math.abs(math.sin(tick() * sine_speed)) )
	local cf = Necks[1].C0:Lerp(CFrame.Angles(angle, 0, 0), lerp_mod)
	for i, v in next, Necks do task.wait()
		v.C0 = cf
	end
end

Also making it less laggy will make it so you can make it smoother

Why don’t you try using TweenService? It’s much smoother