I am making a boat system which allows players to drive boats on a part ocean, not terrain water. In order to do this I am using body velocity and body gyro to move the boat.
However, I have the issue where whenever the player drives the boat into an obstacle, it rotates the boat upwards and now increases the boats y axis, making the boat sail outside of the water (see video below)
I dont believe this is anything to do with the body gyro or velocity as whenever the player does this their properties seem to remain constant.
Here is the script I use to perform boat movement:
local seat = script.Parent
local data = seat.Configuration
local boat = seat.Parent
local heroSeats = boat.heroSeats
local owner = nil
local running = false
local x = 0
local y = boat.PrimaryPart.Orientation.Y
local playerPetsFolder = workspace.Player_Pets
local tweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(
2,
Enum.EasingStyle.Sine,
Enum.EasingDirection.Out
)
local function handleSittingHeroes()
local playerPets = playerPetsFolder:FindFirstChild(owner.Name):GetChildren()
local currentPet = 0
if #playerPets >= 1 then
for i, seat in pairs(heroSeats:GetChildren()) do
if seat:FindFirstChildWhichIsA("Weld") then continue end
currentPet += 1
local pet = playerPets[currentPet]
if pet then
pet.PrimaryPart.CFrame = seat.CFrame
pet.PrimaryPart.AssemblyLinearVelocity = Vector3.new(0,0,0)
pet.PrimaryPart.AssemblyAngularVelocity = Vector3.new(0,0,0)
pet.PrimaryPart.AlignPosition.Enabled = false
pet.PrimaryPart.AlignOrientation.Enabled = false
seat:Sit(pet.Humanoid)
end
end
end
if currentPet < #playerPets then
print("some pets were missed")
end
end
seat.ChildAdded:connect(function(w)
if w.className == "Weld" and w.Name == "SeatWeld" then
local char = w.Part1.Parent
local player = game.Players:FindFirstChild(char.Name)
if player ~= nil then
if player.Name ~= boat.Name then--player doesnt own boat - kick them out
w:Destroy()
char.Humanoid.Jump = true
return
end
--setting up boat ready to drive
seat.Anchored = false
owner = player
player.tempValues.isSeated.Value = true
player.tempValues.canSwing.Value = false
handleSittingHeroes()
boat.PrimaryPart:SetNetworkOwner(player)
seat.ChildRemoved:connect(function(w2)
if w2 == w then
player.tempValues.isSeated.Value = false
player.tempValues.canSwing.Value = true
player = nil
end
end)
seat.BodyVelocity.maxForce = Vector3.new(1, 1, 1) * data.MaxForce.Value
seat.BodyGyro.maxTorque = Vector3.new(1, 1, 1) * 1000000000000
local spd = 0
while owner == player do--while player is driving boat
seat.BodyVelocity.velocity = Vector3.new(seat.CFrame.lookVector.X,0,seat.CFrame.lookVector.Z) * data.currentSpeed.Value
wait()
end
--handling wheen player exits boat
seat.BodyVelocity.velocity = Vector3.new(0, 0, 0)
seat.BodyVelocity.maxForce = Vector3.new(0, 0, 0)
seat.BodyGyro.maxTorque = Vector3.new(0, 0, 0)
data.currentSpeed.Value = 0
seat.Anchored = true
seat.AssemblyLinearVelocity = Vector3.new(0,0,0)
seat.AssemblyAngularVelocity = Vector3.new(0,0,0)
end
end
end)
local function speedHandler()
if seat.Throttle == 1 then--accelerating
if data.currentSpeed.Value < data.MaxSpeed.Value then
if data.currentSpeed.Value + data.Acceleration.Value > data.MaxSpeed.Value then
data.currentSpeed.Value = data.MaxSpeed.Value
else
data.currentSpeed.Value += data.Acceleration.Value
end
end
elseif seat.Throttle == 0 then--slow boat down
if data.currentSpeed.Value < 0 then
if data.currentSpeed.Value + (data.Acceleration.Value*3) > 0 then
data.currentSpeed.Value = 0
else
data.currentSpeed.Value += data.Acceleration.Value*3
end
elseif data.currentSpeed.Value > 0 then
if data.currentSpeed.Value - data.Acceleration.Value*3 < 0 then
data.currentSpeed.Value = 0
else
data.currentSpeed.Value -= data.Acceleration.Value*3
end
end
else--reverse
if data.currentSpeed.Value > -data.MaxSpeed.Value then--can still speed up reverse
if data.currentSpeed.Value - data.Acceleration.Value < -data.MaxSpeed.Value then
data.currentSpeed.Value = -data.MaxSpeed.Value
else
data.currentSpeed.Value -= data.Acceleration.Value
end
end
end
end
seat.Changed:connect(function()
if not running then
local cur = seat.Steer
local cur2 = seat.Throttle
running = true
while (cur ~= 0 or cur2 ~= 0) do
y = y - seat.Steer * data.TurnSpeed.Value
if seat.Steer == -1 then
x = 5
elseif seat.Steer == 1 then
x = -5
else
x = 0
end
speedHandler()
seat.BodyGyro.cframe = CFrame.new(0, 0, 0) * CFrame.Angles(0, math.rad(y), math.rad(x))
wait()
end
running = false
end
end)
If anyone has any thoughts on how I could fix this it would be greatly appreciated. I’ve had a deep look on the devforum and havent been able to find a solution.