This is the first time that I've attempted to make a vehicle on my own, so it might be a little iffy.

My issue is that when the network owner is changed, the boat will go back to the last position that the occupant was at when they had last driven it.

Example:

The first player could drive the boat for a bit and leave. The boat will then return to it's initial position before the ownership was set.

Let's say that the first player then waited till about 10 others used the same boat.

Once this player then jumps back on to drive the boat, it will return to the position that they exited it.

It happens at the exact moment that the NetworkOwnership is switched to nil, or to another player.

Video of problem;

https://www.youtube.com/watch?v=XptL4AZY4DE&ab_channel=AllMight

ServerScript for when the boats driver changes:

local boat = script.Parent
local vehicleSeat = boat:WaitForChild("VehicleSeat")
local engine = boat:WaitForChild("Engine")
local bodyGyro = engine:WaitForChild("BodyGyro")
local bodyPosition = engine:WaitForChild("BodyPosition")
local controlClient = script:WaitForChild("ControlClient")
local players = game:GetService("Players")

local newControl = nil
local origin = boat:GetPivot()
local currentPosition = bodyPosition.Position
local currentGyro = bodyGyro.CFrame

local function clearSettings()
	if newControl ~= nil then
		newControl.Disabled = true
		newControl:Destroy()
	end
	for _, v in pairs(boat:GetChildren()) do
		if v:IsA("BasePart") and v.Anchored == false then
			v:SetNetworkOwner(nil)
		end
	end
end

vehicleSeat:GetPropertyChangedSignal("Occupant"):Connect(function()
	local driver = vehicleSeat.Occupant
	origin = boat:GetPivot()
	currentPosition = bodyPosition.Position
	currentGyro = bodyGyro.CFrame
	
	if driver ~= nil then
		if newControl ~= nil then
			newControl:Destroy()
		end
		local character = driver.Parent
		local player = players:GetPlayerFromCharacter(character)
		if player ~= nil then
			newControl = controlClient:Clone()
			
			for _, v in pairs(boat:GetChildren()) do
				if v:IsA("BasePart") and v.Anchored == false then
					v:SetNetworkOwner(player)
				end
			end
			
			newControl.Parent = character
			newControl.Disabled = false
		end
	elseif driver == nil then
		clearSettings()
	end
end)

LocalScript which is placed inside the player's character so they can control the boat.

local isBoat = script:WaitForChild("IsBoat")
local boat = (isBoat.Value)
local vehicleSeat = boat:WaitForChild("VehicleSeat")
local engine = boat:WaitForChild("Engine")
local bodyGyro = engine:WaitForChild("BodyGyro")
local bodyPosition = engine:WaitForChild("BodyPosition")

while true do
	if vehicleSeat.Throttle == 1 then
		local currentPosition = boat:GetPivot() * CFrame.new(-5, 0, 0)
		local newVectors = Vector3.new(currentPosition.X, 51, currentPosition.Z)
		bodyPosition.Position = newVectors
	elseif vehicleSeat.Throttle == -1 then
		local currentPosition = boat:GetPivot() * CFrame.new(15, 0, 0)
		local newVectors = Vector3.new(currentPosition.X, 51, currentPosition.Z)
		bodyPosition.Position = newVectors
	end
	if vehicleSeat.Steer == 1 then
		bodyGyro.CFrame = boat:GetPivot() * CFrame.Angles(math.rad(-15), 0, 0)
	elseif vehicleSeat.Steer == -1 then
		bodyGyro.CFrame = boat:GetPivot() * CFrame.Angles(math.rad(15), 0, 0)
	elseif vehicleSeat.Steer == 0 then
		bodyGyro.CFrame = boat:GetPivot() * CFrame.lookAt(boat:GetPivot().Position, boat:GetPivot().LookVector * 15)
	end

	wait(0.05)
end