I have a skinned-mesh ocean and I want to make things float. I attached a video and as you can see it kind of works but not entirely. I was wondering why this is and if anyone has any idea on how to fix / improve this. Thanks!
Ocean Script:
local RunService = game:GetService("RunService")
local waveModel = workspace:WaitForChild("Wave")
local plane = waveModel:WaitForChild("Plane")
local bones = {}
for _, v in ipairs(plane:GetDescendants()) do if v:IsA("Bone") then table.insert(bones, v) end end
local amplitude, wavelength, speed = 2, 32, 2
local function waveOffset(basePos, t)
local height = amplitude * math.sin((basePos.X + basePos.Z) / wavelength - speed * t)
return Vector3.new(0, height, 0)
end
local boneData = {}
for _, bone in ipairs(bones) do
local pos = bone.CFrame.Position
boneData[#boneData+1] = {bone = bone, originCFrame = bone.CFrame, originPos = pos}
end
RunService.Heartbeat:Connect(function()
local t = tick()
for _, d in ipairs(boneData) do
local offset = waveOffset(d.originPos, t)
d.bone.CFrame = d.originCFrame * CFrame.new(offset)
end
end)
_G.GetWaveHeightAt = function(position)
return amplitude * math.sin((position.X + position.Z) / wavelength - speed * tick())
end
Buoyancy Script:
local RunService = game:GetService("RunService")
while not _G.GetWaveHeightAt do wait() end
local folder = workspace:WaitForChild("BuoyantParts")
for _, m in ipairs(folder:GetChildren()) do
if m:IsA("Model") and m.PrimaryPart then
local p = m.PrimaryPart
p:SetNetworkOwner(nil)
p.BodyPosition.MaxForce = Vector3.new(1e5,1e5,1e5)
p.BodyGyro.MaxTorque = Vector3.new(1e5,1e5,1e5)
end
end
RunService.Heartbeat:Connect(function()
for _, m in ipairs(folder:GetChildren()) do
if m:IsA("Model") and m.PrimaryPart then
local p, cf = m.PrimaryPart, m.PrimaryPart.CFrame
local fY = _G.GetWaveHeightAt((cf*CFrame.new(0,0,-40)).Position)
local bY = _G.GetWaveHeightAt((cf*CFrame.new(0,0,50)).Position)
local rY = _G.GetWaveHeightAt((cf*CFrame.new(10,0,0)).Position)
local lY = _G.GetWaveHeightAt((cf*CFrame.new(-10,0,0)).Position)
local hover = _G.GetWaveHeightAt(cf.Position) + p.Size.Y/2
local _, yaw, _ = cf:ToOrientation()
local angX = math.atan2(fY - bY, 90)
local angZ = math.atan2(rY - lY, 20)
p.BodyPosition.Position = Vector3.new(cf.Position.X, hover, cf.Position.Z)
p.BodyGyro.CFrame = CFrame.Angles(0, yaw, 0)*CFrame.Angles(angX,0,angZ)
end
end
end)
Video:
Again, any ideas would be amazing. Thanks!