Boat rotation issue

I tried to fix this glitch but im out of ideas rn.

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local Ship = script.Parent
local Root = Ship:WaitForChild("Root")
local Movements = Ship:WaitForChild("Movements")

local ShipSeats = {}
local Module = {}
local ShipOwner = nil
local ShipSeat = nil

local currentSpeed = 0
local currentleftRotateSpeed = 0
local currentRightRotateSpeed = 0
local speed = 40;
local rotateSpeed = 100
local rightTorque = 0
local leftRotate = 0

function Module:Setup()
	for i,v in pairs(Ship:GetDescendants()) do
		if v.ClassName == "Part" or v.ClassName == "UnionOperation" or v.ClassName == "Seat" or v.ClassName == "MeshPart" then
			local w = Instance.new("WeldConstraint")
			w.Part0 = Root
			w.Part1 = v
			w.Parent = Root

			v.Anchored = false
			v.CanCollide = true
			v.Massless = v.Name ~= "Root"
		end
	end
	
	for i,v in pairs(Ship:GetChildren()) do
		if v.ClassName == "Seat" then
			table.insert(ShipSeats, #ShipSeats+1, v)
			if v:FindFirstChild("Ride") then
				ShipSeat = v;
			end
		end
	end
end

Module:Setup()

local BodyGyro = Root:WaitForChild("BodyGyro")
local BodyVelocity = Root:WaitForChild("BodyVelocity")

for i,v in pairs(ShipSeats) do
	if v.ClassName == "Seat" then
		v:GetPropertyChangedSignal("Occupant"):Connect(function()
			ShipOwner = nil
			if not v:FindFirstChild("SeatWeld") then
				return
			end

			if not v.SeatWeld.Part0 or not v.SeatWeld.Part1 then
				return
			end
			
			--[[
			local CombatDisable = Instance.new("Folder")
			CombatDisable.Name = "CombatDisable"
			CombatDisable.Parent = v.SeatWeld.Part1.Parent or nil
			]]
			
			if v:FindFirstChild("Ride") then
				ShipOwner = Players:GetPlayerFromCharacter(v.SeatWeld.Part1.Parent) or nil
				
				if ShipOwner == nil then
					if v.SeatWeld.Part1.Parent:FindFirstChild("Humanoid") then
						v.SeatWeld.Part1.Parent.Humanoid.Jump = true
					end
					return
				end
				
				BodyGyro.CFrame = Root.CFrame
			end
		end)
	end
end

local moveVectors = {
	["Left"] = 0, 
	["Right"] = 0,
	["Front"] = 0,
	["Back"] = 0,
}

local Water = workspace:WaitForChild("Water")
local function checkVectors()
	for i,v in pairs(moveVectors) do
		local ray = Ray.new(Ship.PrimaryPart.CFrame.p, (i == "Left" and Ship.PrimaryPart.CFrame.rightVector * -2) or (i == "Right" and Ship.PrimaryPart.CFrame.rightVector * 2) or (i == "Front" and Ship.PrimaryPart.CFrame.lookVector * 2) or Ship.PrimaryPart.CFrame.lookVector * -2)
		local hit, hitPos, material = workspace:FindPartOnRayWithIgnoreList(ray, {Ship, Water})
		if hit and hit.Parent then
			moveVectors[i] = 0
		end
	end
end

Movements.OnServerEvent:Connect(function(Player, input, tf)
	if Player ~= ShipOwner then
		return
	end
	
	if tf == nil then
		return
	end
	
	local val = 1
	if tf == false then
		val = 0
	end
	
	if input == Enum.KeyCode.W then
		moveVectors["Front"] = val
	elseif input == Enum.KeyCode.D then
		moveVectors["Right"] = val
	elseif input == Enum.KeyCode.A then
		moveVectors["Left"] = -val
	elseif input == Enum.KeyCode.S then
		moveVectors["Back"] = -val
	end
end)

RunService.Heartbeat:Connect(function()
	if ShipOwner and ShipOwner.Character then
		checkVectors()
		
		if currentleftRotateSpeed > rotateSpeed then
			currentleftRotateSpeed = rotateSpeed
		elseif currentleftRotateSpeed < 0 then
			currentleftRotateSpeed = 0
		end
		
		if currentRightRotateSpeed > rotateSpeed then
			currentRightRotateSpeed = rotateSpeed
		elseif currentRightRotateSpeed < 0 then
			currentRightRotateSpeed = 0
		end
		
		if moveVectors["Left"] == -1 and moveVectors["Right"] == 0 then
			currentleftRotateSpeed = currentleftRotateSpeed + 1
			
			if currentRightRotateSpeed >= 1 then
				currentRightRotateSpeed = currentRightRotateSpeed - 1
			end
			
			BodyGyro.P = currentleftRotateSpeed * 17.5
			BodyGyro.CFrame = Ship.ShipOwnerSeat.CFrame * CFrame.fromEulerAnglesXYZ(0, math.rad(10), 0)
		elseif moveVectors["Right"] == 1 and moveVectors["Left"] == 0 then
			currentRightRotateSpeed = currentRightRotateSpeed + 1
			
			if currentleftRotateSpeed >= 1 then
				currentleftRotateSpeed = currentleftRotateSpeed - 1
			end
			
			BodyGyro.P = currentRightRotateSpeed * 17.5
			BodyGyro.CFrame = Ship.ShipOwnerSeat.CFrame * CFrame.fromEulerAnglesXYZ(0, math.rad(170), 0)
		else
			if currentRightRotateSpeed >= 1 then
				currentRightRotateSpeed = currentRightRotateSpeed - 1
			end
			
			if currentleftRotateSpeed >= 1 then
				currentleftRotateSpeed = currentleftRotateSpeed - 1
			end
			
			BodyGyro.CFrame = Root.CFrame
		end
		
		if (moveVectors["Front"] == 1) or (moveVectors["Back"] == -1) then
			if moveVectors["Back"] == -1 then
				currentSpeed = currentSpeed - 0.2
			else
				currentSpeed = currentSpeed + 0.2
			end
			
			if currentSpeed > speed then
				currentSpeed = speed
			elseif currentSpeed < -speed then
				currentSpeed = -speed
			end
		else
			if currentSpeed > 0 then
				currentSpeed = currentSpeed - 0.2
			elseif currentSpeed < 0 then
				currentSpeed = currentSpeed + 0.2
			end
		end
	else
		if currentSpeed > 0 then
			currentSpeed = currentSpeed - 0.2
		elseif currentSpeed < 0 then
			currentSpeed = currentSpeed + 0.2
		end
		BodyGyro.CFrame = Root.CFrame
	end
	
	BodyVelocity.Velocity = Root.CFrame.rightVector * -currentSpeed
end)

Bump. Still need a way to fix this. (20 char)

1 Like

Did you ever figure out how to fix this?
Sorry, I also need help with this issue.

Try setting the maxforce property of the bodygyro to be 0 on x and z
BodyGyro.MaxForce = Vector3.new(0,"Some large number here",0)

This will make it where the boat can only rotate on the Y axis, if you still want the boat to be able to rotate on X and Z but in a limited angle that require a bit of math help, if you want that functionality you can contact me thru discord

Thedagz#4176