Help needed: Script to Muffle Audio Realtime

Hello!

I’m in a bit of a pickle and I could really use some help with a script. I’m trying to create a script that muffles every audio behind a wall or if far away in Realtime, but I’m having no luck. :face_with_diagonal_mouth:


I’ve tried searching for existing solutions, but I couldn’t find anything that matches what I’m looking for. I’ve also tried experimenting with different code, but nothing seems to be working.

Here’s a basic idea of what I’m trying to achieve: when a sound is played on one side of the wall, it should be significantly reduced in volume on the other side of the wall and muffles the sound. Think of it like a real-life wall, where sound waves are absorbed or blocked by the material.


If anyone has any experience with this kind of script or knows of any existing solutions, I would greatly appreciate any help or guidance. I’m willing to learn and adapt to any solution that works.

Please let me know if you can help me out!

Thanks in advance!

i am in need of this too. please tell me if you find anything!

1 Like

i think i found it. it’s a kind of SoundEffect, which can be applied to either Sounds or SoundGroups (multiple sounds that use the same effects & options).

There are multiple kinds of SoundEffect classes (different effects) that you can use, but the specific one that messes with high and low frequencies is EquilizerSoundEffect.

it automatically sets the volume of all three categories of frequencies (low, med, high) to 0, so when you apply the effect, you’ll have to turn up the ones you want up. i believe the more muffled a sound gets, the lower the higher frequencies get. so keep those down.

according to this part of the SoundGroup docs (the ONLY part i could find with an effect example in motion), you would build it like this:

-- create the effect, and parent it to the sound
local effect = Instance.new("EqualizerSoundEffect")
effect.Parent = mySound --any sound here

-- set properties for the effect
effect.HighGain = 0
effect.MidGain = 0.5
effect.LowGain = 1        -- you can mess with these to get whatever result you want!

im a bit late, but hopefully it helps! (the docs can get vague sometimes)

1 Like

Thanks for replying!!!

I thought nobody was going to reply at this point…

So I read a bit about the EqualizerSoundEffect at the Roblox Creator Hub… and I found what I was looking for… but only the effect…

Muffle Effect:
HighGain = -80
LowGain = 10
MidGain = -80

Now, I need a system that checks the sound based on where the listener is and checks if there’s a wall in front of the sound or not…

If there is, then it enables the effect…

If not, then it disables the effect…(In an open environment (no wall), sounds propagate freely, allowing listeners to perceive their full frequency range and intensity.)

I found a post that was helpful because this is exactly what I need!

Is this an efficient way of muffling audio? The video shows exactly what I need for my project… And I just don’t know how to make it or where to start…

Heres some videos on what I need or how I want the system to work: Audio occlusion in Unity ; roblox procedural sound propagation demo

1 Like

the way the guy originally did it in that first post looks a little performance-heavy and complex. i mean, despite it being accurate, i feel like you can still cheat the way it’s done and do other easier.

let’s imagine a build like this:

you have three rooms, each of which is connected with their own doorways (which i will call “portals” because the post you linked kind of called it as such).
sound is playing from room 1, player is in room 3.

here’s two roughly thought out ways on the top of my head:

1) rooms and/or portals

this is based off the first post you sent (the one trying to be more accurate/complex), but a little more simpler to pull off.
because these rooms are each connected with a door inbetween them, i’m going to first order the rooms in a list like this:

-- room 1 -- portal 1 -- room 2 -- portal 2 -- room 3
-- ^ sound                                     ^ player

i think you can kind of see where i’m going to go with this.
you can detect where the sound is and the player is between rooms however you want (either collisions, or checking the position every few frames or so, etc.).

the key point to take out of this is for every “room” or “portal” farther away the player is, the more muffled the sound will get.
i’m using both rooms and portals because you can be a room, but still be able to hear fine through the doorway/portal because nothing is blocking it from the other room–explained at the very end.

code-like, it could look something like this roughly (not to be used, just to show the process):

-- (local script because this can affect players differently based on their positions)

-- making a list for the sounds (or you can call for it from somewhere else):
local sounds = [Workspace.Sound1, Workspace.Sound2 ...]

-- making a dictionary for the rooms, and their muffling power:
local roomList = {
   {order = 1, name = "room1", mufflePower = 0.3},
   {order = 2, name = "portal1", mufflePower = 0.1}  -- ....
}

RunService.Heartbeat:Connect(function()  --(repeating however much you want ...)
     -- some function to get where the player is
     local CurrentLoc = GetPlayerRoomLocation(somePlayer)

     for _, CurrentSound in ipairs(sounds) do  -- loop through sounds
           -- some function to get the sound's location
           local CurrentSoundLoc = GetSoundRoomLocation(CurrentSound)
           
           local mufflePower = 0
           for i=CurrentLoc.order, CurrentSound.order, 1 do   -- for each room inbetween ..
                   mufflePower += roomList[i].mufflePower -- add muffle power
           end

           -- do something to change the sound's muffle with the new mufflePower
     end
)

this will work if you have rooms like the drawing above, were they constantly turn and move around, and aren’t in one straight hallway. the muffling is caused by sound trying to vibrate its way through hard surfaces (walls), resulting in the higher frequencies to be subdued, but obviously that’s not going to be realistic in a straight line of multiple rooms with no walls inbetween. so this one is really for more realistic mazy-turny areas, where you don’t want player to hear something through a wall even though the path to reach that point is very long (imagine very sound-proof walls).

if you do want that, though, i’d imagine the next kind would be easier to do:

2) wall collisions

sounds can both “bounce” off of things, which is good for #1, since the farther away the sound is, the harder it is for its vibrations to bounce to you, but it can also be “absorbed” by materials, some more than others.

if you’re less concerned by accuracy, and more just want it to be muffled behind ANY kind of wall (and not worry about long hallways, this one’s for you.

now, you don’t need a list of rooms, but you might want to get a good list of “walls” you want to be able to “collide” with the sounds. a simply stupid but easy way i thought of at the top of my head is just to label any “walls” you want with a specific collision group. you can just check it that way.

last time i checked on roblox docs, i didn’t find anything for segment/line collisions that grab more than one object (raycasting only shoots for one collision and is infinite in one direction), so the only other way i could think of is by using a long part (within the same collision group as your walls) connecting between you and the sound. you can then use the Part:GetTouchingParts to get a list of colliding walls. idk if it’s good performance wise–someone else would have to put in a couple of cents for that–but it should technically work.
kind of like this:

local sounds = [Workspace.Sound1, Workspace.Sound2 ...]

-- colliding part
local CollisionPart = --[part here]

RunService.Heartbeat:Connect(function()  --(repeating however much you want ...)

     for _, CurrentSound in ipairs(sounds) do  -- loop through sounds

          -- get the part to transform right between u + sound
          CollisionPart:SetCFrame( ... )

           -- some function to get the sound's location
           local Walls = CollisionPart:GetTouchingParts
           
           local mufflePower = 0.1 * #Walls
           -- perhaps add attributes to the walls if you want varying "muffle power?"

           -- change sound's muffle to mufflePower
           ( ... )
     end
)

if there’s anything segment-wise that can be used for collisions, then great, otherwise, this might be the best for that, LOL. i feel like there is some easier way to check for collisions. but you get the idea.

in the end, you can always:

3) use a bit of both, or go your own direction

for example, you can use the #1 way for muffling sounds through rooms, but also have the #2 way to check if there’s actually no walls inbetween you and the sound–only that you’re just very far away. y’know, what i was talking about with using the portals earlier.
and by all means, if you find a better way as you work through it, give it a shot! this kind of treads more into game design than scripting. not necessarily how to type it out, but how to concept setting it up.

sorry for the long reply, haha. but i hope it helps you understand!

2 Likes

I think that would work if I only needed one sound to be muffled, but I want all sounds in the game to be muffled… Also, my game would be full of hitboxes (portals).

like typed here before, you could definitely do this to multiple sounds. you would just have to loop through them all each time you “repeat” that muffle check, and change their own muffle effects one at a time.

if youre not sure about grabbing all of the applicable sounds, maybe “create” sounds through another script that not only creates them, but puts them into a global “sound list” for yourself?

and if you’re concerned about performance, a simple room-by-room thing (no portals), or a way to check if you have even just one collision blocking you from the sound would be good enough, i bet.