Making an audio play near terrain water optimized?

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)
1 Like

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 Like

Thanks for the reply but that’ll take a while in my messy map

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.

1 Like

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

i’m not sure about the optimization of it though…

https://create.roblox.com/docs/reference/engine/classes/Terrain#ReadVoxels

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.

B

I found the best results with these properties and played around with the volume property to achieve it.

you’re right, im just making life harder for myself

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.