Ship not working or Gerstner waves

I am trying to make a floating system for a ship using gerstner waves but its not sitting on the waves.

Heres my code

local A = 1 -- amplitude (basically wave height)
local WL = 2 -- wave length (what is this)
local k = (2*math.pi/WL) -- wave number
local f = 5 -- wave frequency (idk)
local w = (2*math.pi*f) -- angular frequency
local t = .1 -- time (speed of the waves cuh)
local B = 5 -- vertical offset

local mesh = workspace:WaitForChild("Plane")
local Bones = {}

for i, v in mesh:GetChildren() do
	if v:IsA("Bone") then
		table.insert(Bones, v)
		
	end
	
end

local rs = game:GetService("RunService")
local st = tick()

local ship = workspace:WaitForChild("Ship")

rs.Heartbeat:Connect(function(dt)
	local cu = tick() - st
	for i, v in Bones do
		local x = v.Position.X -- x axis
		local y = v.Position.Y

		v.Position = Vector3.new(x,A*math.cos(k*x-w*t*cu)+B,v.Position.Z)
		
	end
	
	local sx = ship.Position.X
	local sy = ship.Position.Y
	ship.Position = Vector3.new(sx, A*math.cos(k*sx-w*t*cu)+B, ship.Position.Z)
	
end)

A video showing the ship
robloxapp-20241212-1631151.wmv (497.2 KB)

1 Like

It looks like your ship position is relative to the world, while your bone positions are relative to something else right?
( I haven’t worked with bones very much )

yea, the bones are relative to the mesh plane. how would i make the ship be on the waves though or how would i make it relative to the plane

Yes, and one way to fix this is to work with Bone.WorldPosition when calculating each Bone’s Y offset, so that everything is in world space. The other way is to transform the ship position to be in the same coordinate space as the Bones (the Bones’ parent part). e.g.:

local shipTransformedCFrame = BoneParentPart.CFrame:Inverse() * ship.CFrame
local sx = shipTransformedCFrame.Position.X

FWIW, it’s best to animate Bones by leaving their CFrame property alone and just setting the Bone.Transform property to be CFrame.new(0, A*math.cos(k*x-w*t*cu)+B, 0) each frame. The Transform property is what you use to animate a Bone every frame, the CFrame is meant to be more of the rest pose, not something you change at every frame.

1 Like

Add the y position of the mesh plane’s root part to the ship’s y position in your calculation.

That’s not enough, you need the ship’s animated Y offset to be the same as a Bone that’s at the same world X and Z location. I don’t mean it has to have the position of one of the Bones, just that it has to be doing its calculations in same coordinate system as the Bones are. Adjusting just the Y will make the ship height correct if it’s at the same X,Z position as the ocean mesh, but out of phase most other places.

You probably also want the ship to have some additional constant Y offset from the ocean mesh part, as needed to get the ship submerged the right amount in the water (i.e. to set the draft).

this had fixed the issue by using the worldposition method but now my ship is going under the wave when its going up and vice versa when the wave is going down

This could be because of how your Bones are oriented. Are the Bones aligned so tha their up direction is the same as world up, i.e. +Y? Like if you add +1 to the Y position of a Bone, does it go up?

yea whenever i add 1 to the y in position it goes up
heres an example video
robloxapp-20241212-1733321.wmv (692.5 KB)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.