For some reason it seems occlusion does not work when using Resonance audio with FMOD: I have set a room in Unity with a blocking wall, put a sound source with a studio event emitter, and a studio listener on my camera. Within FMOD I have one sound using Resonance Audio source with occlusion, and a Resonance audio listener on the master bus, prefader. Now when I start the game I do get immersive sound when moving around the audio source, but no occlusion when I get behind the wall. I should add that I do get occlusion when using Resonance audio directly inside Unity, so I suppose the feature should be working within FMOD as well - otherwise why put it?
One more thing, Unity considers the source as 2D panning for some reason (as soon as I put a Resonance Audio source instead of, say, an FMOD object spatializer). Can it have anything to do with my issue?
I am using FMOD Studio 1.10.09
Thank you for all you do, FMOD is truly inspiring!
So basically my question is: has anyone managed to make occlusion function within Unity using FMOD and Resonance Audio? And if so, does it include something I forgot? For instance there is no on/off button for occlusion inside the FMOD plugin, so maybe it is deactivated and is accessible somewhere else?
So to make sure it means the occlusion knob is not functional by default on the Resonance Audio Source plugin within FMOD? But why include it in the documentation without a word of warning then? Something like “be aware that this function alone can’t be activated as such and requires scripting”. Thank you very much for your answer, highly appreciated!
The occlusion knob works just fine! It’s like any other effect property: It controls the amount of occlusion applied by the effect, and changing the value of the knob changes the amount of occlusion that’s applied. If you want to change the value of the occlusion knob dynamically, add automation to that knob, and use a parameter to control its value via that automation.
Unfortunately, there’s no way for FMOD Studio to magically know how much occlusion you want to affect any given event: No game engine tells FMOD Studio when there’s an obstacle between the listener and the event emitter by default, and even if game engines did tell us that information, FMOD Studio wouldn’t know how much occlusion that particular obstacle was supposed to apply.
If you want obstacles in your game world to occlude events in a dynamic way, your game’s code must track the relative positions of event emitters and occluding obstacles relative to the listener, determine when occlusion should occur and how much occlusion should be applied when it does, and then pass that information to FMOD Studio by setting the value of the parameter that controls your event’s occlusion.
ok that is clear now, I guess I was confused because this works automatically in Unity without having to use any ray casting or such: one just sets an occlusion value, which is only applied when an object gets in front of the direct source. So that there is no automation needed, same as near-field gain is set but can only be felt once an object gets near. I suppose that makes quite a difference with the FMOD version of the plug then, and I will now look into it with the useful info you provided. Thank you very much!
Hello again, now I have followed your advice and managed to use a linecast in order to get occlusion to work, so first thank you very much, BUT… two things: the amount of occlusion, when pushed to the max (10), is roughly equivalent to a value of 1 when the Resonance Audio plugin is directly used within Unity. And mostly, inside Unity two obstacles (like two walls) occlude more than one, meaning there is a huge difference in the way this is calculated, and this without any programming. So that, unless I am mistaken, the occlusion feature within the FMOD version of the Resonance Audio Source plugin is very different than the original one. I mean, I suppose there is a way to extend a linecast in order to detect multiple obstacles, but still the max occlusion value would be the same (10), so there would not be any audible difference. If anybody else has made any comparisons I am very much interested, as I am trying to get the best of both worlds - and again, thank you !
@MA_ORDON It looks like you’re getting a compiler error since the script can’t see ‘Internal Editor Utility’. Depending on your version of Unity it may have a different name for the Unity Editor now.
For Unity 2020.3.15 it’s using UnityEditorInternal
at the top make sure it says using UnityEditorInternal; if it’s a similar Unity version.
This is how I have the code inserted in StudioListenerEditor.cs
public class StudioListenerEditor : Editor
public SerializedProperty attenuationObject;
private void OnEnable()
attenuationObject = serializedObject.FindProperty("attenuationObject");
/// Occlusion modification allows raycast to check which layers should be occluded
public override void OnInspectorGUI()
var index = serializedObject.FindProperty("ListenerNumber");
EditorGUILayout.IntSlider(index, 0, FMOD.CONSTANTS.MAX_LISTENERS - 1, "Listener Index");
//Begin Occlusion Mod
var mask = serializedObject.FindProperty("occlusionMask");
int temp = EditorGUILayout.MaskField("Occlusion Mask", InternalEditorUtility.LayerMaskToConcatenatedLayersMask(mask.intValue), InternalEditorUtility.layers);
mask.intValue = InternalEditorUtility.ConcatenatedLayersMaskToLayerMask(temp);
//End Occlusion Mod
Hi @Glitchbyte ! Thank you for your help! This solved the error. I’m now getting another error when I try to create the AudioOcclusion script, specifically: Assets/AudioOcclusion.cs(46,51): error CS0103: The name ‘FmodResonanceAudio’ does not exist in the current context
Do you know whats going on here? I really appreciate your help!
Yeah, after one of the FMOD updates, I noticed it stopped working since FMOD no longer made some scripts accessible from outside their code, so instead I inserted the occlusion script directly into the StudioEventEmitter.cs script right at the bottom of the script below the IsPlaying() function.
/// Checks occlusion value returned by layers hit with raycast on update
//Begin Occlusion MOD
currentOcclusion = 0.0f;
else if (Time.time >= nextOcclusionUpdate)
nextOcclusionUpdate = Time.time + occlusionDetectionInterval;
currentOcclusion = occlusionIntensity * ComputeOcclusion(transform);
instance.setParameterByName(occlusionParameterName, currentOcclusion, false);
//Debug.Log("Value to FMOD =" + currentOcclusion);
public static Transform ListenerTransform
if (listenerTransform == null)
var listener = GameObject.FindObjectOfType<StudioListener>();
if (listener != null)
listenerTransform = listener.transform;
private static Transform listenerTransform = null;
// Pre-allocated raycast hit list for occlusion computation.
private static RaycastHit occlusionHits = new RaycastHit[maxNumOcclusionHits];
public static float ComputeOcclusion(Transform sourceTransform)
var listener = GameObject.FindObjectOfType<StudioListener>();
occlusionMaskValue = listener.occlusionMask;
float occlusion = 0.0f;
if (ListenerTransform != null)
Vector3 listenerPosition = ListenerTransform.position;
Vector3 sourceFromListener = sourceTransform.position - listenerPosition;
int numHits = Physics.RaycastNonAlloc(listenerPosition, sourceFromListener, occlusionHits,
//Debug.Log("Hits =" + numHits);
for (int i = 0; i < numHits; ++i)
if (occlusionHits[i].transform != listenerTransform &&
occlusionHits[i].transform != sourceTransform)
occlusion += 1.0f;
if (Physics.Raycast(listenerPosition, sourceFromListener, out hit, Mathf.Infinity, occlusionMaskValue))
Debug.DrawRay(listenerPosition, sourceFromListener * hit.distance, Color.yellow);
Debug.DrawRay(listenerPosition, sourceFromListener * 1000, Color.white);
Debug.Log("Did not Hit");
/// Maximum allowed number of raycast hits for occlusion computation per source.
public const int maxNumOcclusionHits = 10;
/// Occlusion layer mask.
private static int occlusionMaskValue = -1;
/// Source occlusion detection rate in seconds.
public const float occlusionDetectionInterval = 0.2f;
//End Occlusion Mod
Also at the top of the script, right after public float OverrideMaxDistance = -1.0f;
I added the section with
//Occlusion Mod Begin
public bool occlusionEnabled = false;
public string occlusionParameterName = null;
public float occlusionIntensity = 1f;
public float currentOcclusion = 0.0f;
public float nextOcclusionUpdate = 0.0f;
//Occlusion Mod End
Basically instead of using the AudioOcclusion.cs component, I’m just using it through the fmod event emitter