Custom Water + Ships

i’m aware that the method that @Soliform is talking about is also used here:

It seems like the code here is using a combination of gerstner waves and adding them together. You can reuse this code for the most part. Basically what I’d do is this:
Sample the ocean height at these points:
image
Then, subtract the left’s position from the right’s and the front’s from the rear’s. This will make vectors pointing through them, like this
image
You can use the green line as the forward vector and the purple line as the right vector. The up vector is the cross product of these two. This is how you calculate the rotation of the ship.
For the position, you can just calculate the y position at the center of mass then subtract it by the waterline height and position the ship there.

Edit: For movement, you’ll need to use a drag equation.

3 Likes

I’ll do this now! Thanks for the help your amazing!

we got a part to float up and down using this code, however we are stuggling to get it to float at angles.

local Controller = require(game.CollectionService:GetTagged("2A9746FA-AD27-46FA-B54C-4468D23213B2")[1])
--local Controller = workspace:WaitForChild("Workspace"):WaitForChild("Ocean"):WaitForChild("Controller")

local displacement = Controller.GetDisplacementAtPosition
local RunService = game:GetService("RunService")

local part = script.Parent

local UpVector = Vector3.new(0, 1, 0)

RunService.Heartbeat:Connect(function()
	local Tile = Controller.Object.Parent.Tiles:FindFirstChildOfClass("MeshPart")
	
	local GlobalMoveCFrame = CFrame.lookAt(Vector3.new(), 
		workspace.CurrentCamera.CFrame.LookVector - workspace.CurrentCamera.CFrame.LookVector:Dot(UpVector) * UpVector, UpVector)
	local GlobalMoveVector = GlobalMoveCFrame:VectorToWorldSpace(Vector3.new(0, 0, 0))
	local Displacement = displacement(part.Position, GlobalMoveVector, part:GetAttribute("Displacement"))
	
	local TargetPosition = part.Position * Vector3.new(1, 0, 1) + Vector3.new(Displacement.X, Tile.Position.Y + Displacement.Y, Displacement.Z)

	part.BodyPosition.Position = TargetPosition
end)

– Gyro

You need something to control rotation, like a BodyGyro or AlignOrientation. Then use the 4 sample points like I showed in the picture and calculate a rotation matrix from them.

1 Like

What do you mean by ‘Sample’ ?

How do you calculate the body gyro?

Like I said, you can get the ocean height at 4 points along the ships hull like I showed in the picture. Then you can do the following:

local xVector = (leftPosition - rightPosition).Unit
local zVector = (forwardPosition - rearPosition).Unit
local yVector = xVector:Cross(zVector)
local gyroCF = CFrame.fromMatrix(Vector3.new(), xVector, yVector, zVector)

1 Like