Make this boat move

Hello! So I am making a horror game and I have a boat in the game that moves smoothly in this path. The thing is I have no clue how to make the boat move smoothly itself while the player is seating in the chair.

I have tried teleporting the boat but that’s not smooth and I want it smooth and slow as possible.

Example:
image

1 Like

You can use TweenService to tween the boat from Point1to Point2, or you can use CFrames and Lerp() smoothly to a position.

I recommend you using TweenService to ween the boat. You can watch a tutorial online or use this tutorial TweenService tutorial

There are 3 ways I can think of:

TweenService
As @cheesy_roblox190 said, Tween the Boat from A to B, If you want a more Linear way of doing it, Use CFrame:Lerp() for this.

Info = TweenInfo.new( -- Stuff for the Tween to Apply
   1, -- Duration
   Enum.EasingStyle.Sine, -- Transition
   Enum.EasingDirection.Out, -- Transition Type
   0, -- Times Repeated?
   false, -- Reversed?
   0 -- Delay
)
TweenService:Create(PrimaryPart, Info, {Position = YourPosition}):Play()

CFrame:Lerp()
This is a Linear way of doing it, almost the same as TweenService

for i = 0,100,.01 do
   wait() -- used for a slower effect
   PrimaryPart.CFrame:Lerp(PointB.CFrame, i) -- i = Percentage Completed
   -- for each iteration, the Item will advance
end

for the i part, each time the iteration is completed, i will add up, since we have it at .01 (1/100) it will add .01, which in turn will make it slow, and maybe smooth


Velocity
Apply a Velocity to the Boat to move towards a position

while true do
task.wait()
PrimaryPart.AssemblyLinearVelocity = PrimaryPart.CFrame.LookVector * 20
-- Applies a Velocity based on the way the Part is looking
end
1 Like

Velocity imo atleast would be the smoothest and easiest as it’s mostly physics based. CFrame and Lerp often look robotic/

3 Likes

how would I be able to check if the player sat on the boat?

The the Occupant of the Seat, if its nil, nobody is sitting in it, Use Changed, or GetPropertChangedSignal for the Seat.

Seat:GetPropertyChangedSignal("Occupant"):Connect(function()
  if Seat.Occupant then
   print"Seat Occupied"
  else
   print"Seat Vacant"
  end
end)

also I wanted the boat to have a couple turns how would I do that? By adding more tweens?

I guess you could tween the CFrame to where you want it to look.
If you use lerp it changes the orientation to the goal’s CFrame orientation.

You can also use CFrame.lookAt but won’t be smooth unless you tween it.
Sorry if I’m bad at explaining.

I would read about CFrames to if you dont understand this CFrame Document

If you tween the CFrame (on the server) it will be choppy and not smooth. Instead, you should tween the position/cframe of an AlignPosition and an AlignOrientation. These two instances combined work just like setting the cframe (when they are set to use enough force) but they use physics to do so, which causes the client to smooth out the motion.

I got a little carried away and programmed this:

-- The speed of the boat
local SPEED = 10

local boat = script.Parent
-- When you make a new boat make sure to set the AlignPosition and AlignOrientation to the CFrame where you want the boat
local alignPosition = boat.PrimaryPart.AlignPosition
alignPosition.Position = boat.PrimaryPart.Position
local alignOrientation = boat.PrimaryPart.AlignOrientation
alignOrientation.CFrame = boat.PrimaryPart.CFrame

-- A list of seats to trigger the boat moving
local seats = {
	boat.SeatOne;
	-- Add your other seats
}

local pathPart = workspace.PathPart-- Set to a part with attachments named "1", "2", "3" etc. which represent the path of the boat


local hasStarted = false
local function startBoat()
	-- Only start the boat when someone sits for the first time
	if hasStarted then
		return
	end
	hasStarted = true
	
	print("Boat starting path!")
	
	-- Instead of tweening boat cframe, tween CFrame value so we can update the boat cframe with the mover constraints
	local goalCFrameValue = Instance.new("CFrameValue")
	goalCFrameValue.Value = boat.PrimaryPart.CFrame
	goalCFrameValue.Parent = boat.PrimaryPart
	
	-- Update the align position and align orientation
	local function onGoalChanged()
		alignOrientation.CFrame = goalCFrameValue.Value
		alignPosition.Position = goalCFrameValue.Value.Position
	end
	
	-- Update the align position and align orientation when the CFrame value is changed
	onGoalChanged()
	goalCFrameValue.Changed:Connect(function()
		onGoalChanged()
	end)
	
	-- Go through each attachment, make and play a tween, go to the next attachment when the tween is done
	local currentIndex = 1
	local pathAttachment = pathPart:FindFirstChild(tostring(currentIndex))
	
	while pathAttachment do
		local newCframe = pathAttachment.WorldCFrame
		local oldCframe = goalCFrameValue.Value
		
		local distance = (newCframe.Position - oldCframe.Position).Magnitude
		
		local tweenInfo = TweenInfo.new(distance/SPEED, Enum.EasingStyle.Linear)
		local tween = game:GetService("TweenService"):Create(goalCFrameValue, tweenInfo, {Value = newCframe})
		tween:Play()
		tween.Completed:Wait()
		
		currentIndex += 1
		pathAttachment = pathPart:FindFirstChild(tostring(currentIndex))
	end
	
	print("Boat finished path!")
	-- Boat finished path, maybe destroy in a few seconds or something
end

-- Run the start boat function whenever someone sits (startBoat has a debounce so it only can start once)
for _, seat in ipairs(seats) do
	seat:GetPropertyChangedSignal("Occupant"):Connect(startBoat)
end

Here is a place file that demonstrates how the code works:

Smooth Path Boat.rbxl (38.3 KB)

1 Like

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