Hi
I have been trying to create boat physics for my Gerstner Waves but every time i attempt to do so, the boat just falls to the ocean floor.
I have tried using the 3 waves within the formula to calculate the height of the water. I would then use that height and compare it with nodes on all 4 sides of the boat which then tells a gyro part in the middle to rotate with CFrame.
Here is some media related to my problem
Entire Boat in Explorer
This is the Gerstner Wave formula found in StarterPlayerScripts:
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local speedMultiple = 0.0025 -- Smaller is faster wave movement, higher is slower
local maxDistance = 350 -- Distance in studs from character, to stop calculating bone position
local origPosTable = {}
local LocalPlayer = Players.LocalPlayer
function GerstnerWave(SamplePosition ,Wavelength, Direction, Steepness, Gravity, SampleTick)
local k = (2 * math.pi) / Wavelength
local a = Steepness/k
local d = Direction.Unit
local c = math.sqrt(Gravity / k)
local f = k * d:Dot(Vector2.new(SamplePosition.X,SamplePosition.Z)) - c * SampleTick
local cosF = math.cos(f)
--Displacement Vectors
local dX = (d.X * (a * cosF))
local dY = a * math.sin(f)
local dZ = ( d.Y * (a * cosF))
return Vector3.new(dX, dY, dZ)
end
local plane = workspace:WaitForChild("Ocean"):WaitForChild("Plane")
for _, bone in pairs(plane:GetChildren()) do
if bone:IsA("Bone") then
origPosTable[bone] = bone.Position
end
end
local function getNodeHeight(node, speedCounter)
local SamplePosition = node.WorldPosition
local Wave1 = GerstnerWave(SamplePosition, 150, Vector2.new(1, 0), .05, 1, speedCounter)
local Wave2 = GerstnerWave(SamplePosition, 175, Vector2.new(0, .3), .2, 1.25, speedCounter)
local Wave3 = GerstnerWave(SamplePosition, 200, Vector2.new(1, 1), .1, 1.5, speedCounter)
local TotalDisplacement = Wave1 + Wave2 + Wave3
return TotalDisplacement.Y
end
local function getCameraHeight(position, speedCounter)
local Wave1 = GerstnerWave(position, 150, Vector2.new(1, 0), .05, 1, speedCounter)
local Wave2 = GerstnerWave(position, 175, Vector2.new(0, .3), .2, 1.25, speedCounter)
local Wave3 = GerstnerWave(position, 200, Vector2.new(1, 1), .1, 1.5, speedCounter)
local TotalDisplacement = Wave1 + Wave2 + Wave3
return TotalDisplacement.Y
end
local function updateCameraBlur(cameraPosition, speedCounter)
local waveHeight = getCameraHeight(cameraPosition, speedCounter)
local cameraUnderWater = cameraPosition.Y - 2.1 < waveHeight
if cameraUnderWater then
game.Lighting.Blur.Size = 15
game.Lighting.Atmosphere.Density = 0.95
game.Lighting.Atmosphere.Offset = 1
Players.LocalPlayer.PlayerGui.Swells.Volume = 2.5
workspace.Music.EqualizerSoundEffect.HighGain = -11.6
workspace.Music.EqualizerSoundEffect.MidGain = -11.6
Players.LocalPlayer.PlayerGui.GoUnder:Play()
else
game.Lighting.Blur.Size = 4
game.Lighting.Atmosphere.Density = 0.5
game.Lighting.Atmosphere.Offset = 0
Players.LocalPlayer.PlayerGui.Swells.Volume = 0
workspace.Music.EqualizerSoundEffect.HighGain = 10
workspace.Music.EqualizerSoundEffect.MidGain = 10
Players.LocalPlayer.PlayerGui.GoUp:Play()
end
end
local skipCounter = 0
local speedCounter = 0
game:GetService("RunService").Heartbeat:Connect(function()
skipCounter += 1
speedCounter += speedMultiple
if skipCounter >= 2 then
skipCounter = 0
local char = LocalPlayer.Character
if char and char:FindFirstChild("HumanoidRootPart") then
for _, bone in pairs(plane:GetChildren()) do
if bone:IsA("Bone") then
if origPosTable[bone] then
if (char.HumanoidRootPart.Position - bone.WorldPosition).Magnitude <= maxDistance then
local SamplePosition = bone.WorldPosition
local Wave1 = GerstnerWave(SamplePosition, 150, Vector2.new(1, 0), .05, 1, speedCounter)
local Wave2 = GerstnerWave(SamplePosition, 175, Vector2.new(0, .3), .2, 1.25, speedCounter)
local Wave3 = GerstnerWave(SamplePosition, 200, Vector2.new(1, 1), .1, 1.5, speedCounter)
local TotalDisplacement = Wave1 + Wave2 + Wave3
bone.Position = origPosTable[bone] + TotalDisplacement
end
end
end
end
end
local cameraPosition = workspace.CurrentCamera.CFrame.Position
updateCameraBlur(cameraPosition, speedCounter)
end
end)
I am confused how people manage to make working boat physics while all I can do is implement a camera system where it changes atmosphere when I dip my camera under.
Any tips or help would be greatly appreciated because I can’t figure out exactly what to do here.