Custom Water + Ships

  1. What do you want to achieve? I am trying to make a ship float on my custom water (made using mesh deformation) I’m trying to make it rock back, forwards and side to side. I’ve seen people use raycasting for this but I struggle doing this.

  2. What is the issue? I can’t get boats to float on my custom water. Here are some scripts that I have tried already:


local bow = script.Parent.Bowray

local stern = script.Parent.Sternray

local wavelist = workspace.Ocean2.Plane

-- Set an origin and directional vector

local bowray = bow.Position

local sternray = stern.Position

local rayDirection = Vector3.new(0, -100, 0)

-- Build a "RaycastParams" object and cast the ray

local raycastParams = RaycastParams.new()

raycastParams.FilterDescendantsInstances = {bowray.Parent}

raycastParams.FilterType = Enum.RaycastFilterType.Whitelist

local raycastParams2 = RaycastParams.new()

raycastParams2.FilterDescendantsInstances = {sternray.Parent}

raycastParams2.FilterType = Enum.RaycastFilterType.Whitelist

local bowrayresult = workspace:Raycast(bowray, rayDirection, raycastParams)

local sternrayresult = workspace:Raycast(sternray, rayDirection, raycastParams)

local part2, pos2 = workspace:FindPartOnRayWithWhitelist(sternrayresult, wavelist)

local part, pos = workspace:FindPartOnRayWithWhitelist(bowrayresult, wavelist)

if part or part2 then

script.Parent.CFrame = CFrame.new(pos, pos2)

end

  1. What solutions have you tried so far? I’ve been scanning around the developer forum but have had no luck!
3 Likes

You cant use raycasting because mesh deformation doesnt interact with raycasts too accurately. You need to instead sample the height of water at various points along the ship’s hull and calculating their bouyant force. From there you can compare it against the weight and displacement to get a final force acting on the ship, then combine all the sample points against the center of mass to get an angle and position of the ship.

5 Likes

To be honest the other reply would probably work, but I have tried the buoyancy method, and it’s extremely laggy and buggy, instead I would reccomend using maybe 3-4 body positions along the ship with a Y force, and change their height according to the wave.

3 Likes

I’ll try this. Thanks for the help!

Using multiply body positions is a bad idea. They will counter each other to try dominate for which will have the control.

1 Like

what do you recommend me doing?

The first comment would probably work. I’ve seen somewhere where they used multiple different points to track the magnitude of the waves.

1 Like

Alright! Thanks for the help, i’ll try it.

How do i calculate the buoyant force of an object? I’m aware that it goes something like **Fb = Vs × D × g . I find it slightly confusing.

For the volume (Vs) you use the volume of the ship thats below the waterline. D is the density, in this case salty water is 1023.6 kg/m³, and g is gravity which can be workspace.Gravity or 198.2.

1 Like

Do you have any methods of sampling the height of water of various points of the hull of the ship? (i’m not sure how to do this)

this is super helpful! thanks!

Well, how do you think the ocean is rendered? Theres some code in there that calculates the Y position of the ocean at a given X,Z coordinate.

If they body position are in different spots this shouldn’t happen unless: the MaxForce isn’t set to (0, n, 0) or the difference between the two heights is more than the distance between the two body positions.

Using a few BodyPositions is probably the easiest way.

Edit:
RatiusRat is correct, I thought there was a ApplyAtCenter property for BodyPositions. The BodyPositions have to affect separate assemblies then, so you’d need to use BallSocketConstraints or hinges–anything that makes a new assembly and connects it to the larger one.

A better way is to calculate the points, find the orientation and position relative to the center of mass, then use a BodyPosition and BodyGyro to position the boat.

2 Likes

In the code with waves I don’t see any Y position, however there are X,Z coordinates

 X = Instance2.CFrame.Position.X,
 Z = Instance2.CFrame.Position.Z

Are these the sample positions i need?

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

Did you program the ocean? Making a ship base that reacts to waves is very complex so you gotta know what you’re doing.

edit: Not sure, it seems it uses gerstner waves is what I can tell from that

I created this version myself, I saw a post on the dev forum and was inspired by it. I wanted to try it myself. I’m not super experienced in coding, however I managed to create this using a gerstner wave pattern.

will the code i put above work as our sample heights?

Have you tested that theory though? I’ve welded two parts together and both have a bodyposition. They are set at different positions yet only 1 is active while the other is cancelled.