How to make a ship loop through the same path?

So I want to make a ship sail forever on the same path. I have tried this, but it does not work:

local waypoints = game.Workspace.Waypoints:GetChildren()
local ship = game.Workspace.ShipTest
local tweenservice = game:GetService("TweenService")
while true do
	for i = 1,#waypoints do
		local point = waypoints[i]
		ship.PrimaryPart.CFrame = CFrame.lookAt(point,nextpoint)
		tweenservice:Create(ship.PrimaryPart, TweenInfo.new(3), {CFrame = i.CFrame}):Play()
		wait(3)
	end
end

:frowning:

1 Like

There are some things wrong with this code.

  1. “nextpoint” was never defined
  2. “i” is an index and not a part, so you can’t derive a CFrame from this
  3. CFrame.lookat requires Vector3s, not base parts
  4. You can’t tween a model’s primarypart, unfortunately. You would have to weld the ship to the primary part, anchor the primary part, and unanchor the rest of the parts.

Here’s what I’d do:

local waypoints = game.Workspace.Waypoints:GetChildren()
local ship = game.Workspace.ShipTest
local tweenservice = game:GetService("TweenService")

-- Function that welds model's parts to PrimaryPart
local function weldModel(model)
	local primaryPart = model.PrimaryPart
	primaryPart.Anchored = true
	for _, part in model:GetDescendants() do
		if part:IsA("BasePart") and part ~= primaryPart then
			local weld = Instance.new("WeldConstraint", primaryPart)
			weld.Part0 = primaryPart
			weld.Part1 = part
			part.Anchored = false
		end
	end
end
weldModel(ship)

while true do
	for i = 1, #waypoints do
		local point = waypoints[i]
		
		-- If ship is going through last loop, set the nextpoint to 1 for the beginning 
		-- Otherwise, add 1 from the point
		local nextindex = i == #waypoints and 1 or i+1
		local nextpoint = waypoints[nextindex]		

		-- Face the ship from point's position to nextpoint's position
		ship.PrimaryPart.CFrame = CFrame.lookAt(point.Position, nextpoint.Position)
		
		-- Tween to nextpoint's CFrame
		tweenservice:Create(ship.PrimaryPart, TweenInfo.new(3), {CFrame = nextpoint.CFrame}):Play()
		wait(3)
	end
end

I actually haven’t tested this, so let me know if anything comes up :slight_smile:

2 Likes

Ohhhh!!! I understood a bit more now, thank you. It still has some issues like, it rotates a bit weird and it doesn’t go through the waypoints in order. I’m not sure how I’ll work it out but I might manage. :hugs:

The reason it’s out of order is :GetChildren() does not return the children in any specific order.
Once you’ve retrieved these children and stored them in your waypoints variable, you can sort them yourself like so:

table.sort(waypoints, function(pointA, pointB)
	return pointA.Name < pointB.Name
end)
1 Like