How would I go about getting an object to float on Gerstner Waves.
I have made my gerstner waves by following this tutorial here
What I have tried
I have tried the code here and got a very weird glitchy result. Even when I got the code running semi-correctly I could tell that was not really what I wanted.
What I want
I’m looking for mainly the basics of how to do this and not really looking for full pieces of code. If full code is provided it will (obviously) make my task much easier. And of course I would love for my end result to be like @tyridge77’s System , @RawEggTheGreatIX 's System or this System (I forgot who made it)
Thanks in advance!
(This is my first post don’t be to hard on me lol)
I think the main issue with your old code is that the gernster wave formula doesn’t just return a new Y value. It also returns new X and Z values. When you ignore the X and Z values, it will appear out of sync.
Thank you so much for the reply! The issue is that I never really made any code… because I have no knowledge to go about doing it.
However I did find some code from @TheCursedSpudhere that kind of worked here it is:
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 RunService = game:GetService("RunService")
RunService.Heartbeat:Connect(function()
local Height1 = GerstnerWave(script.Parent.Position,10.0,Vector2.new(0,1),5.0,2.0,tick()).Y
local Height2 = GerstnerWave(script.Parent.Position,10.0,Vector2.new(1,0),5.0,2.0,tick()+1).Y
local NewHeight = (Height1/2)+(Height2/2)
script.Parent.Position = Vector3.new(script.Parent.Position.X,NewHeight,script.Parent.Position.Z)
end)
Thank you for the reply! Yes I believe you are right. And again I do not want to take credit for work that is not mine all credit for the old code goes to @TheCursedSpud .
sorry but Im having a hard time understanding the problem. The waves seem to deform properly. Is there a specific behavior you had in mind? If so what is it.
Ok so the problem is: I cant figure out how to script a buoyancy or floating system (Idk if this helps but it is for boats). I have found a method (the code above) And it did not work super great… Im looking for some help for just the basics on how to do this if and if im still stuck I might need some more help later.
For each part that you want to float, calculate the wave height at the position of that part. This would be the same thing that you have in your Heartbeat handler.
Then, if your part is above that point, don’t do anything. If it’s below that point, add a BodyForce or something.
Thank you so much! Thats a really good idea but I have a question… So if im being honest i dont really understand why that heartbeat handler even works… If possible could you show me some example code? (excluding variables and the body force idea you had(i could add that later)
So the GerstnerWave function takes in a position (+some wave control variables), and returns the height at that position.
Sort of like if you put in a latitude and longitude into your GPS and it told you the elevation.
You didn’t say, but I’m assuming you have a grid of Bone objects inside your mesh object that defines the ocean surface. If you move those bones around, the surface of the ocean would follow.
Heartbeat runs every frame. So every frame, for every bone, it:
Calls the GerstnerWave function to ask “what height should the ocean be at this position?”
Thank you so much! Thats probably the best explanation i have heard! And yes i should have mentioned earlier i am using bones…
So in a sense how would i “grab” the nearest bones position in a floating/bouncy script?
Next would i take that position and find the average of where the floating part should be?
I’m assuming you have a mesh plane made of triangles, and a bone at each vertex.
Option 1. Interpolate positions from neighboring bones.
First, figure out which triangle (mesh face) you’re on or above. Get the positions for the three vertices of that triangle, either by finding the bones associated with the vertices, or by recomputing their heights. The exact details depend on your exact setup, and whether or not you have an easy way to associate bones with grid positions.
Second, once you have the three bones closest to you (or at least their heights), you can interpolate between their heights based on your exact position within their triangle. This is just a little math. It’s a weighted average of the three points.
Option 2 is easier but may give imperfect results if your bones are spaced out really far.
Just call your wave function, but pass it your (the buoyant part’s) position instead of a bone’s. It gives you the height of the water at that point.
I say it might give you imperfect results, because the bones are connected with straight triangles rather than the smooth underlying curves.
Hey thank you! Option 2 works but… Its kind of out of sync and stuff. So if I’m going to do this I should probably take the time to just try Option 1. One question: how would I find what Bones the Floating part is above in the first place? Again sorry for so many questions mesh deformation and working with bones is all new to me.
So… No they are not ordered under columns but just numbered under the Plane itself.
I just realized they are kinda random???
Although they are numbered as far as Can tell they are random… You would think bone 1 would be closest to 0 right? well not in my case. The nearest bone to 0 is 35. The bones appear to start on the x axis from right to left.