Audio Occlusion in Unity: Snapshots vs. Raycasting

When sound passes through walls, it becomes muffled. This is called audio occlusion. Unfortunately, Unity cannot simulate this effect automatically (yet), but it’s easy enough create manually! So In this tutorial, we'll explore two main ways to simulate occlusion in Unity, one is very simple and straightforward, and another more complex but flexible way (with caveats):
Using
AudioMixer
SnapshotsUsing
Physics.Raycast
+AudioLowPassFilter
Option 1: Audio Occlusion Using Snapshots
This method is great for simple room setups, where sounds become clean (without any effects) when the player enters a room and muffled when the player is outside.
We'll use a radio in a room as an example, and demonstrate how its sound changes depending on whether the player is inside or outside the room.
Step 1: Add a radio sound source
Create an empty
GameObject
. You can name itRadio
Add an
AudioSource
component to it.Assign a looping audio clip (any audio will do)
Set Spatial Blend to 3D
You can mess around with Max Distance, something like 15 is probably good.
Step 2: Create an Audio Mixer
Create an audio mixer if you haven't yet (Assets > Create > Audio Mixer)
Right click the
Master
group => Create Child Group => name itSFX
Step 3: Create Snapshots
In the Mixer window, click Snapshotד
Click the
+
button twice to create two snapshots:Clear
andMuffled
Configure Muffled
snapshot:
Select the
Muffled
snapshotClick on the
SFX
groupIn the Inspector, check Low Pass Filter and set cutoff frequency to 800 Hz. The value here is again something to mess around with, it depends on the thickness of the wall and so on.
Step 4: Assign the AudioSource to the Mixer
Select the
Radio
GameObjectIn the AudioSource component, set Output to
SFX
Step 5: Create a trigger zone for the room
Create an empty GameObject called
RoomTrigger
Add a Box Collider and check Is Trigger
Scale and position it so it fills the room
Step 6: Add a script to trigger the correct snapshot
Create a new script called OcclusionTrigger.cs
:
using UnityEngine;
using UnityEngine.Audio;
public class OcclusionTrigger : MonoBehaviour
{
public AudioMixerSnapshot clearSnapshot;
public AudioMixerSnapshot muffledSnapshot;
public float transitionTime = 0.5f;
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
clearSnapshot.TransitionTo(transitionTime);
}
private void OnTriggerExit(Collider other)
{
if (other.CompareTag("Player"))
muffledSnapshot.TransitionTo(transitionTime);
}
}
Step 7: Setup the Player and assign snapshots
Make sure the Player GameObject has a Collider and is tagged as
Player
Assign the
Clear
andMuffled
snapshots in the Inspector for theRoomTrigger
Done! Now when the player enters the room, the sound becomes clear. When they step outside, it’s muffled.
Option 2: Audio Occlusion Using Raycasting
This method gives more precise occlusion and works per sound source. It’s ideal for enemies or moving NPCs. Just keep in mind that raycasting every frame can get expensive if overused, so it’s best to apply this method selectively to important sound sources only.
We’ll use Physics.Raycast
to check if there's a wall between the sound source and the listener, and apply a lowpass filter if blocked.
Step 1: Create the sound emitter
Create a GameObject called
Enemy
Add an
AudioSource
and assign a looping soundSet Spatial Blend to 3D
Add an
AudioLowPassFilter
componentSet the cutoff frequency to 22000 Hz (default clear sound)
Step 2: Create the script
Create a new script called AudioOcclusion.cs
:
using UnityEngine;
[RequireComponent(typeof(AudioLowPassFilter))]
public class AudioOcclusion : MonoBehaviour
{
public Transform listener;
public LayerMask occlusionMask;
public float clearCutoff = 22000f;
public float muffledCutoff = 800f;
public float transitionSpeed = 5f;
private AudioLowPassFilter lowPass;
void Start()
{
lowPass = GetComponent<AudioLowPassFilter>();
}
void Update()
{
Vector3 direction = listener.position - transform.position;
float distance = direction.magnitude;
if (Physics.Raycast(transform.position, direction, out RaycastHit hit, distance, occlusionMask))
{
lowPass.cutoffFrequency = Mathf.Lerp(lowPass.cutoffFrequency, muffledCutoff, Time.deltaTime * transitionSpeed);
}
else
{
lowPass.cutoffFrequency = Mathf.Lerp(lowPass.cutoffFrequency, clearCutoff, Time.deltaTime * transitionSpeed);
}
}
}
Step 3: Assign references
Drag the
Main Camera
(which should have the AudioListener) into thelistener
fieldSet the
occlusionMask
to include layers that should block sound. If you haven't set up custom layers for obstacles, just leave it asDefault
and make sure the wall (or walls) are on that layer.Also make sure the walls have colliders
That’s it! Now the enemy sound will get muffled when a wall is between it and the player.
Summary
Snapshots are best for room based transitions (inside/outside)
Raycasting is more flexible and realistic, especially for moving sources or complex environments, but it's also more expensive, so use it with care
You can mix both approaches in one project for performance and realism
Subscribe to my newsletter
Read articles from Omer Faran directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
