After much trial and error, I’ve decided to see if I can get help here…
I’ve been trying to make a custom ocean (not smooth terrain) using Gerstner Waves similar to tyridge77’s and RawEggTheGreatIX’s. – i don’t know if RawEggTheGreatIX used Gerstner Waves, but it has the affect I’m looking for.
I’ve been looking for a bunch of ways to do it, and I simply cannot figure out how to work it. The farthest I’ve gotten so far is making the plane mesh with bones, but have failed to fathom how to loop through the bones and work them with the Gerstner Wave formula. I’ve messed around with a few different fluid scripts such as this one.
I have had the opposite problem as you lol, i know how to get the valeus but not set those values and transform them to a mesh. It isnt gerstner its perlin however the concept is the same
As far as the mesh goes, I made a 10mx10m (x,z) plane and put a bone on every vertice (did this using a python script to save time)… perlin seems like a very interesting way to do it but I am still unsure as to how I would make it work with the bones.
Usually what you should to is make a function for returning a Y position of a certain X&Z, (or atleast thats how I did it)
something like this:
local function GetYFromWave(pos)
local result = -- use noise, gerstner or other generation method
return Vector3.new(pos.X,result,pos.Z)
end
Now to generate something, you can use multiple methods. I use a mix of noise and a module that creates patterns similar to gerstner waves
For noise, you would do something like this:
local function GetYFromWave(pos)
local result = math.noise((pos.X+offset)/width, (pos.Z+offset)/width, seed)
return Vector3.new(pos.X,result,pos.Z)
end
for gerstner, something like this im pretty sure:
local function GetYFromWave(pos)
local resultX = math.sin(pos.X)
local resultZ = math.sin(pos.Z)
return Vector3.new(pos.X+resultX,resultX+result.Z,pos.Z+resultZ)
end
Hey there, sorry for the annoyance, but I just wanted to ask that how would I go about putting it into the mesh, I’ve been trying but didnt get it. I used the heartbeat even for it but it doesnt move, so could you help me with that?
My current script is this:
local function GetYFromWave(pos)
local resultX = math.sin(pos.X)
local resultZ = math.sin(pos.Z)
return Vector3.new(pos.X+resultX, resultX+resultZ + 20, pos.Z+resultZ)
end
local ocean = workspace.Ocean.Plane
local bones = ocean:GetChildren()
game:GetService("RunService").Heartbeat:Connect(function(dt)
for i, v in pairs(bones) do
v.WorldPosition = GetYFromWave(v.WorldPosition)
end
end)
Please note that I havent been taught about things such as sin, cosine, gerstner and all that so I might act dumb at times, sorry for that.
Also, how exactly would you go about adding a direction vector to this formula? The waves are pretty good but would look even better if there is some way to change their direction.
Here’s my current code (works nicely)
local bones = workspace.Ocean.Plane:GetChildren()
local speedCounter = 0
local function GetYFromWave(pos)
local amplitude = script:GetAttribute("Amplitude")
local frequency = script:GetAttribute("Frequency")
speedCounter += script:GetAttribute("Speed") / 10 -- dividing just to prevent extremely small numbers.
local resultX = amplitude * math.sin(pos.X * frequency + speedCounter)
local resultZ = amplitude * math.sin(pos.Z * frequency + speedCounter)
return Vector3.new(pos.X + resultX, resultX + resultZ, pos.Z + resultZ)
end
game:GetService("RunService").Heartbeat:Connect(function()
for i, bone in pairs(bones) do
if bone:IsA("Bone") then
bone.Transform = CFrame.new(GetYFromWave(bone.Position))
end
end
end)