Flying Dutchmen Pirate Ship Boat
create.roblox.com/store/asset/16433707385
Boat with Retractable Anchor
Here is the code that powers the boat!
The main goal was to make a boat template that can be easily modified
This was done by requiring the only object to make the boat is the Buoy mainly. But I added the anchor because I really wanted it. I learned a lot about rope constraints and maybe next Iโll make a fishing pole!
local console = script.Parent
local boat = console.Parent
local Seat = console.Parent.VehicleSeat
--.VehicleSeat
local params = RaycastParams.new()
params.FilterDescendantsInstances = {workspace.Terrain}
params.FilterType = Enum.RaycastFilterType.Whitelist
local AngularVelocity = script.AngularVelocity
local LinearVelocity = script.LinearVelocity
--// Sail the Boat
local CurA = 1
local MaxA = 12
local Boater = boat["Buoy"]
local function unachor(bool)
for i, v in boat:GetDescendants() do
if v:IsA("BasePart") then
v.Anchored = bool
v.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
--Anchor.AssemblyLinearVelocity=Vector3.new(0,0,0)
v.AssemblyAngularVelocity = Vector3.new(0, 0, 0)
end
end
end
unachor(true)
local floatmaterial = Enum.Material.Water
local eposoffset = Vector3.new(0, 15, 0)
local sposoffset = Vector3.new(0, 5, 0)
--local eposoffset= Vector3.new(0, 0, -(Boater.Size.Z/2))
local function CheckFront()
local BoaterP = Boater.CFrame:ToWorldSpace(CFrame.new(Vector3.new(0, 0, -Boater.Size.Z / 2)))
local seatpos = BoaterP.Position - Vector3.new(0, 5, 0)
--local sPos = BoaterP:ToWorldSpace(sposoffset).Position
local ePos = BoaterP:ToWorldSpace(CFrame.new(eposoffset)).Position
local ray = workspace:Raycast(seatpos, ePos - seatpos, params)
if ray and ray.Material == floatmaterial then
--print("Check Front Passed")
return true
end
--print("Check Front Failed")
return nil
end
-- Get the rope constraint object
local rope = boat.Winch.Winch.RopeConstraint
local Anchor = boat.Winch["Metal Anchor"]
-- Store the original length of the rope
local originalLength = rope.Length
-- Define a function to check the tension of the rope
local function checkTension()
-- Get the current length of the rope
local currentLength = rope.Length
-- Get the current distance between the attachments
local currentDistance =
((Anchor.CFrame:ToWorldSpace(Anchor.Attachment1.CFrame)).Position - rope.Parent.Position).Magnitude + 1
--local currentDistance = ((Anchor.CFrame).Position-rope.Parent.Position).Magnitude
-- Compare the current length with the original length
if currentLength <= currentDistance then
-- The rope is stretched and has tension
return true
else
-- The rope is slack or coiled and has no tension
--print("The rope has no tension")
end
-- Compare the current distance with the current length
if currentDistance < currentLength then
-- The rope is coiled and has extra length
-- print("The rope is coiled")
elseif currentDistance > currentLength then
-- The rope is slack and has less length
-- print("The rope is slack")
else
-- The rope is neither coiled nor slack and has the same length as the distance
-- print("The rope is neither coiled nor slack")
end
return false
end
-- Define a function that takes an object and a density as parameters
local function setCustomPhysicalProperties(object, density)
-- Check if the object is a valid BasePart
if object:IsA("BasePart") then
-- Get the current physical properties of the object
local currentProperties = object.CustomPhysicalProperties
-- Create a new PhysicalProperties object with the given density and the same friction, elasticity, frictionWeight, and elasticityWeight as the current properties
local newProperties =
PhysicalProperties.new(
density,
currentProperties.Friction,
currentProperties.Elasticity,
currentProperties.FrictionWeight,
currentProperties.ElasticityWeight
)
-- Set the CustomPhysicalProperties of the object to the new properties
object.CustomPhysicalProperties = newProperties
else
-- Print an error message if the object is not a valid BasePart
print("Invalid object. Please provide a BasePart.")
end
end
-- Call the function to check the tension of the rope
local function DropAnchor()
rope.WinchEnabled = false
rope.WinchResponsiveness = 45
rope.WinchForce = 10000
setCustomPhysicalProperties(Anchor, 100)
Anchor.Massless = false
Anchor.Anchored = false
boat.Winch.RopeProp.Anchored = false
Anchor.AssemblyLinearVelocity = Vector3.new(0, -10, 0)
rope.Length = 100
task.wait(4)
rope.WinchTarget = 10
rope.WinchEnabled = true
rope.WinchSpeed = 2
repeat
task.wait(1)
until checkTension() == true
Anchor.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
Anchor.AssemblyAngularVelocity = Vector3.new(0, 0, 0)
rope.WinchEnabled = false
Anchor.Anchored = true
boat.Winch.RopeProp.Anchored = true
end
local tweenservice = game:GetService("TweenService")
local goal = {}
local tweeni = TweenInfo.new(.0666)
local function RetractAnchor()
Anchor.Massless = true
Anchor.CanCollide = false
boat.Winch.RopeProp.Anchored = false
setCustomPhysicalProperties(Anchor, .1)
Anchor.Anchored = false
--task.wait(3)
rope.WinchSpeed = 25
rope.WinchEnabled = true
Anchor.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
Anchor.AssemblyAngularVelocity = Vector3.new(0, 0, 0)
rope.WinchTarget = .25
rope.WinchResponsiveness = 90
rope.WinchForce = 20000
local twe = tweenservice:Create(rope, TweenInfo.new(3), {Length = .25})
twe:Play()
twe.Completed:Wait()
rope.WinchForce = 10000
Anchor.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
Anchor.AssemblyAngularVelocity = Vector3.new(0, 0, 0)
repeat
task.wait(.5)
rope.WinchForce = math.max(3000, rope.WinchForce - 1000)
Anchor.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
Anchor.AssemblyAngularVelocity = Vector3.new(0, 0, 0)
until checkTension() == true
rope.WinchEnabled = false
Anchor.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
Anchor.AssemblyAngularVelocity = Vector3.new(0, 0, 0)
task.delay(
3,
function()
Anchor.CanCollide = true
end
)
end
local doing = false
Seat.Changed:Connect(
function()
--// Only sail on water
if Seat.Occupant ~= nil and doing == false then
AngularVelocity.AngularVelocity = Vector3.new(0, -1 * Seat.Steer, 0)
LinearVelocity.LineVelocity = 50 * Seat.Throttle
doing = true
RetractAnchor()
task.wait()
unachor(false)
AngularVelocity.Enabled = true
local Occupant = Seat.Occupant
LinearVelocity.Enabled = true
while Occupant == Seat.Occupant do
task.wait()
local seatpos = Boater.Position
local sPos = seatpos + sposoffset
local ePos = seatpos - eposoffset
local ray = workspace:Raycast(sPos, ePos - sPos, params)
-- print(Seat.Steer)
if ray and ray.Material == floatmaterial then
print("Query successful")
task.wait()
if Seat.Throttle ~= 0 then
CurA = math.min(MaxA, CurA + .01)
Seat.Torque = (10 * CurA)
Seat.MaxSpeed = (10 * CurA)
else
task.wait()
CurA = math.max(1, CurA - .01)
end
LinearVelocity.LineVelocity = 50 * (Seat.Throttle * CurA)
LinearVelocity.MaxForce = 10000 + (1000 * math.abs(Seat.Throttle) * CurA)
AngularVelocity.MaxTorque = 10000 + (1000 * math.abs(Seat.Throttle) * CurA)
--- local tween=tweenservice:Create(LinearVelocity,tweeni,{LineVelocity= 50 * (Seat.Throttle*CurA),MaxForce = 10000 + (1000*math.abs(Seat.Throttle)*CurA)})
-- tween:Play()
--- local tween=tweenservice:Create(AngularVelocity,tweeni,{AngularVelocity = Vector3.new(0, -1 * Seat.Steer*math.min(2,CurA), 0),MaxTorque=10000 + (1000*math.abs(Seat.Throttle)*CurA)})
-- tween:Play()
AngularVelocity.AngularVelocity = Vector3.new(0, -.5 * Seat.Steer * math.min(3, CurA), 0)
task.wait()
else
-- task.wait(.3)
-- LinearVelocity.LineVelocity = 50 * (-1*CurA)
-- task.wait(3)
--
end
if Occupant ~= Seat.Occupant then
break
end
end
Occupant = nil
AngularVelocity.Enabled = false
LinearVelocity.Enabled = false
unachor(true)
DropAnchor()
--task.wait()
--unachor(false)--I tried to make it unachored but it gets yeeted :(
Anchor.Anchored = true
doing = false
end
end
)
This is the first iteration so stay tuned for updates! Iโm going to add cannons and perhaps hitpoints