So, I made a post earlier asking how I would make a part float on water terrain. most of the people said just make a water system and whilst going through my old games I found a water system that I clearly did not make, and I think I got it from an open-source dev forum post, but I couldn’t seem to find it.
I do want to make one thing clear: I suck at math; I have no idea how this works. I have spent the past few hours trying to get this to work, but with no prevail. I would like someone to explain to me how this works as well.
here is the code:
local Settings = self._settings
local Direction = Settings.Direction
for _,v in pairs(self._bones) do
local WorldPos = v.WorldPosition
print(WorldPos)
if Direction == EmptyVector2 then
-- Use Perlin Noise
local Noise = self._noise[v]
local NoiseX = Noise and self._noise[v].X
local NoiseZ = Noise and self._noise[v].Z
local NoiseModifier = 5 -- If you want more of a consistent direction, change this number to something bigger
if not Noise then
self._noise[v] = {}
-- Uses perlin noise to generate smooth transitions between random directions in the waves
NoiseX = math_noise(WorldPos.X/NoiseModifier,WorldPos.Z/NoiseModifier,1)
NoiseZ = math_noise(WorldPos.X/NoiseModifier,WorldPos.Z/NoiseModifier,0)
self._noise[v].X = NoiseX
self._noise[v].Z = NoiseZ
end
Direction = Vector2.new(NoiseX,NoiseZ)
else
Direction = GetDirection(Settings,WorldPos)
end
v.Transform = newCFrame(Gerstner(WorldPos,Settings.WaveLength,Direction,Settings.Steepness,Settings.Gravity,self._time))
end
for _, V: Part in pairs(workspace.Floats:GetChildren()) do
local WorldPos = V.Position
V.CFrame = newCFrame(Gerstner(WorldPos,Settings.WaveLength,Direction,Settings.Steepness,Settings.Gravity,self._time))
-- this returns NAN
end
here is the Gerstner function:
local function Gerstner(Position: Vector3,Wavelength: number,Direction: Vector2,Steepness: number,Gravity: number,Time: number)
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(Position.X,Position.Z)) - c * Time
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