How to smoothly make a model curve around a corner when turning

I’m making a tower defense game, and I’m just trying to make the movement look smooth for the enemies.
This is the script I’m using for that:

local function MoveToTween(Enemy: Model, CF: CFrame, NextCF: CFrame)
	local Humanoid = Enemy:FindFirstChildWhichIsA("Humanoid")
	local Root = Humanoid.RootPart
	
	local Distance = (Vector3.new(Root.Position.X, 0, Root.Position.Z) - Vector3.new(CF.Position.X, 0, CF.Position.Z)).Magnitude
	local LookAt = CFrame.new(Root.Position, Vector3.new(CF.Position.X, Root.Position.Y, CF.Position.Z))
	
	local TimeTaken = Distance/Humanoid.WalkSpeed
	
	delay(TimeTaken-15/60, function()
		local StartCFrame = Root.CFrame.Rotation
		local X,Y,Z = Root.CFrame.Rotation:ToOrientation()
		local X2,Y2,Z2 = CFrame.lookAt(CF.Position, NextCF.Position).Rotation:ToOrientation()

		local RotDifference = (Y2 - Y)

		if math.deg(RotDifference) > 180 then
			RotDifference -= math.rad(360)
		end
		if math.deg(RotDifference) < -180 then
			RotDifference += math.rad(360)
		end
		
		if RotDifference then
			for i=1, 30 do
				Root.CFrame = CFrame.new(Root.Position) * StartCFrame * CFrame.Angles(0, RotDifference * (i/30), 0)
				task.wait()
			end
		end
	end)
	
	repeat
		local CurrentDistance = (Vector3.new(Root.Position.X, 0, Root.Position.Z) - Vector3.new(CF.Position.X, 0, CF.Position.Z)).Magnitude
		
		Root.CFrame += LookAt.LookVector * Humanoid.WalkSpeed/60
		task.wait()
	until CurrentDistance <= Humanoid.WalkSpeed/60
end

This works for smoothly rotating the model, and for moving it from one position to another, however it looks a bit off as the direction it’s moving is still snapping like this:

Whereas I want it to turn like this:

Sorry if this is a bit confusing, but I hope you get what I mean.

Many Thanks.

you can use BezierPath module

Yeah thanks this worked. Although it is a little embarrassing putting that much work into the code when I could have done it much simpler like this :sweat_smile::

	local Positions = {}
	for i=1, #Waypoints:GetChildren() do
		Positions[i] = Waypoints:FindFirstChild(tostring(i)).Position
	end
	local NewPath = BezierPaths.new(Positions, 1.8)
	local Length = NewPath:GetPathLength()
	
	local TotalTime = Length/Humanoid.WalkSpeed
	local StartTime = time()
	
	while (Bottom.Position - Waypoints:GetChildren()[#Waypoints:GetChildren()].Position).Magnitude > 0.1 do
		local t = ((time() - StartTime)/TotalTime)
		Root.CFrame = NewPath:CalculateUniformCFrame(t) + Vector3.new(0, BottomOffset, 0)
		task.wait()
	end

Thanks for the help though!

1 Like

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