I’ve tried GetWaterCell, which I found deep down in the intellisense but is deprecated and worked somehow… but, It does about 9261 loops per frame which is not great for low-end devices like mine, and sometimes crashes or breaks something inside my pc
and I have no other idea for fixing it since I did the research and found nothing
any help is greatly appreciated
-- how to setup;
-- create a local script and parent it to `StarterPlayer > StarterCharacterScripts`
-- set the script source to this
-- put the water audio in the script and name it `Shore`
local RunService = game:GetService("RunService")
local character = script.Parent
local distance = 10
local skip = 1
local volume = 0.5
local water = script:WaitForChild("Shore")
RunService.RenderStepped:Connect(function()
local characterPosition = character:GetPivot().Position
local hasWater = false
local nearestDistance = nil
for x=characterPosition.X - distance, characterPosition.X + distance, skip do
for y=characterPosition.Y - distance, characterPosition.Y + distance, skip do
for z=characterPosition.Z - distance, characterPosition.Z + distance, skip do
local water = workspace.Terrain:GetWaterCell(z, y, z)
local position = Vector3.new(x, y, z)
local distance = (characterPosition - position).Magnitude
if water then
if not nearestDistance or distance < nearestDistance then
nearestDistance = distance
end
hasWater = true
end
end
end
end
if hasWater then
local calculatedVolume = math.abs(nearestDistance - distance) * volume
water.Volume = calculatedVolume
else
water.Volume = 0
end
end)
Why?
Just put a Part in the Terrain Water, just at the surface.
Make it Anchored, Transparent, and CanCollide false.
Put the sound in it.
Change the MinRollOffDistance and MinRollOffDistance of the sound so it works for you.
1 water Part is messy?
I have it set up that way in my Steampunk place. A large water place with 3 islands.
I’ve only got 1 2048X2048 sound Part in the water and I’ve got the MaxRollOffDistance set so that as the player walks up the Terrain shoreline the sound gets quieter. As they move above the sound part at ‘sea level’ on the Terrain the water sound goes silent.
heres a snippet of code that determines if a player is submerged
local min = Head.Position - (.1 * Head.Size)
local max =Head.Position + (.1 * Head.Size)
local region = Region3.new(min,max):ExpandToGrid(4)
local material = workspace.Terrain:ReadVoxels(region,4)[1][1][1]
if material == Enum.Material.Water then
--submerged
you should be able to retrofit it to your needs, by increasing the min, max otherwise look into the sample code in api
essentially it returns a table of material(s) and occupancies(?) but I’m sure this is how you would check it more effectively, but if you’re willing and no other solutions come up, I would experiment with this
Audios in parts are likely the best solution for playing audio in specific regions. The method may seem hacky, but it easily outperforms any code. Other methods, including ReadVoxels or anything terrain related, aren’t beginner friendly either.
I found the best results with these properties and played around with the volume property to achieve it.