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.
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
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: