Skip to content

Instantly share code, notes, and snippets.

@athiedmann
Last active October 3, 2023 22:15
Show Gist options
  • Select an option

  • Save athiedmann/437b8a9d19081811b4bb957a096367fe to your computer and use it in GitHub Desktop.

Select an option

Save athiedmann/437b8a9d19081811b4bb957a096367fe to your computer and use it in GitHub Desktop.
Optimize audio occlusion with the WwiseAmbientOcclusion script for Unity. This script checks if player has entered specific zones and applies occlusion appropriately to dynamic change audio playback.
using UnityEngine;
//Uses Logger.cs, there's a commented version using the Unity Debugger wrapped in a region below
public class WwiseAmbientOcclusion : MonoBehaviour
{
#if UNITY_EDITOR
public bool DebugScript = false;
#endif
public GameObject AudioListener;
public GameObject[] WwiseReverbZones;
public AK.Wwise.RTPC[] OcclusionsRTPC;
public float LowPass_Max = 1;
public float Volume_Max = 1;
public string NameOfListener = "ListenerName";
private AK.Wwise.RTPC setRTPCLoPass;
private AK.Wwise.RTPC setRTPCVolume;
private Collider[] reverbZoneColliders;
private bool lastOcclusionState = false;
private void Awake()
{
if (!enabled)
{
Destroy(this);
return;
}
SetupChecks();
GetReverbZoneColliders();
}
void SetupChecks()
{
if (OcclusionsRTPC.Length == 2)
{
setRTPCLoPass = OcclusionsRTPC[0];
setRTPCVolume = OcclusionsRTPC[1];
}
else if (OcclusionsRTPC.Length > 2)
{
Logger.LogWarning($"Remember to set additional RTPC's within the Perform/NoPerformOcclusion() functions of {this.name}");
setRTPCLoPass = OcclusionsRTPC[0];
setRTPCVolume = OcclusionsRTPC[1];
}
else if (OcclusionsRTPC.Length < 2)
{
Logger.LogWarning("Occlusion array not set, returning");
enabled = false;
return;
}
else if (WwiseReverbZones.Length == 0)
{
Logger.LogError("Error — Set the WwiseReverbZones array — bailing");
enabled = false;
return;
}
}
void GetReverbZoneColliders()
{
reverbZoneColliders = new Collider[WwiseReverbZones.Length];
for (int i = 0; i < WwiseReverbZones.Length; i++)
{
GameObject reverbZone = WwiseReverbZones[i];
if (reverbZone != null)
{
reverbZoneColliders[i] = reverbZone.GetComponent<Collider>();
}
}
}
private void Start()
{
if (AudioListener == null || reverbZoneColliders.Length == 0)
{
if (DebugScript) Logger.Log("Returning WwiseAmbientOcclusion, check that AudioListener or Wwise Reverb Zones are properly assigned.");
enabled = false;
return;
}
AkSoundEngine.RegisterGameObj(gameObject);
}
private void Update()
{
bool currentOcclusionState = OcclusionCheck();
if (currentOcclusionState != lastOcclusionState)
{
if (DebugScript) Logger.Log($"{this} occlusion state has changed, setting new state");
switch (currentOcclusionState)
{
case true:
PerformOcclusion();
break;
case false:
PerformNoOcclusion();
break;
}
lastOcclusionState = currentOcclusionState;
if (DebugScript) Logger.Log($"LastOcclusionState set to {lastOcclusionState}");
}
else
{
if (DebugScript) Logger.Log($"{this} occlusion state hasn't changed, returning");
return;
}
}
bool OcclusionCheck()
{
bool isOccluded = false; // Track the occlusion state
foreach (Collider zoneTriggerCollider in reverbZoneColliders)
{
if (zoneTriggerCollider != null && zoneTriggerCollider.bounds.Contains(AudioListener.transform.position))
{
isOccluded = true; // Update the occlusion state
if (DebugScript) Logger.Log("player within occlusion zone");
break; // No need to check the remaining colliders if occlusion is already detected
}
}
return isOccluded;
}
void PerformOcclusion()
{
if (DebugScript)
Logger.Log("Performing Occlusion");
setRTPCLoPass.SetValue(gameObject, LowPass_Max);
setRTPCVolume.SetValue(gameObject, Volume_Max);
}
void PerformNoOcclusion()
{
if (DebugScript)
Logger.Log("No Occlusion Performing");
setRTPCLoPass.SetValue(gameObject, 0);
setRTPCVolume.SetValue(gameObject, 0);
}
}
#region UnityDebugLogScript
//using UnityEngine;
//public class WwiseAmbientOcclusion : MonoBehaviour
//{
//#if UNITY_EDITOR
// public bool DebugScript = false;
//#endif
// [Header("Playback Settings")]
// public GameObject AudioListener;
// public GameObject[] WwiseReverbZones;
// public AK.Wwise.RTPC[] OcclusionsRTPC;
// public float LowPass_Max = 1;
// public float Volume_Max = 1;
// public string NameOfListener = "CameraBrain";
// private AK.Wwise.RTPC setRTPCLoPass;
// private AK.Wwise.RTPC setRTPCVolume;
// private Collider[] reverbZoneColliders;
// private bool lastOcclusionState = false;
// private void Awake()
// {
// if (!enabled)
// {
// Destroy(this);
// return;
// }
// SetupChecks();
// GetReverbZoneColliders();
// }
// void SetupChecks()
// {
// if (OcclusionsRTPC.Length == 2)
// {
// setRTPCLoPass = OcclusionsRTPC[0];
// setRTPCVolume = OcclusionsRTPC[1];
// }
// else if (OcclusionsRTPC.Length > 2)
// {
//#if UNITY_EDITOR
// Debug.LogWarning($"Remember to set additional RTPC's within the Perform/NoPerformOcclusion() functions of {this.name}");
//#endif
// setRTPCLoPass = OcclusionsRTPC[0];
// setRTPCVolume = OcclusionsRTPC[1];
// }
// else if (OcclusionsRTPC.Length < 2)
// {
//#if UNITY_EDITOR
// Debug.LogWarning("Occlusion array not set, returning");
//#endif
// enabled = false;
// return;
// }
// else if (WwiseReverbZones.Length == 0)
// {
//#if UNITY_EDITOR
// Debug.LogError("Error — Set the WwiseReverbZones array — bailing");
//#endif
// enabled = false;
// return;
// }
// }
// void GetReverbZoneColliders()
// {
// reverbZoneColliders = new Collider[WwiseReverbZones.Length];
// for (int i = 0; i < WwiseReverbZones.Length; i++)
// {
// GameObject reverbZone = WwiseReverbZones[i];
// if (reverbZone != null)
// {
// reverbZoneColliders[i] = reverbZone.GetComponent<Collider>();
// }
// }
// }
// private void Start()
// {
// if (AudioListener == null || reverbZoneColliders.Length == 0)
// {
//#if UNITY_EDITOR
// if (DebugScript) Debug.Log("Returning WwiseAmbientOcclusion, check that AudioListener or Wwise Reverb Zones are properly assigned.");
//#endif
// enabled = false;
// return;
// }
// AkSoundEngine.RegisterGameObj(gameObject);
// }
// private void Update()
// {
// bool currentOcclusionState = OcclusionCheck();
// if (currentOcclusionState != lastOcclusionState)
// {
//#if UNITY_EDITOR
// if (DebugScript) Debug.Log($"{this} occlusion state has changed, setting new state");
//#endif
// switch (currentOcclusionState)
// {
// case true:
// PerformOcclusion();
// break;
// case false:
// PerformNoOcclusion();
// break;
// }
// lastOcclusionState = currentOcclusionState;
//#if UNITY_EDITOR
// if (DebugScript) Debug.Log($"LastOcclusionState set to {lastOcclusionState}");
//#endif
// }
// else
// {
//#if UNITY_EDITOR
// if (DebugScript) Debug.Log($"{this} occlusion state hasn't changed, returning");
//#endif
// return;
// }
// }
// bool OcclusionCheck()
// {
// bool isOccluded = false; // Track the occlusion state
// foreach (Collider zoneTriggerCollider in reverbZoneColliders)
// {
// if (zoneTriggerCollider != null && zoneTriggerCollider.bounds.Contains(AudioListener.transform.position))
// {
// isOccluded = true; // Update the occlusion state
// BypassPlugInEffectsRTPCs(isOccluded, zoneTriggerCollider.name);
//#if UNITY_EDITOR
// if (DebugScript) Debug.Log("player within occlusion zone");
//#endif
// break; // No need to check the remaining colliders if occlusion is already detected
// }
// }
// return isOccluded;
// }
// void PerformOcclusion()
// {
//#if UNITY_EDITOR
// if (DebugScript) Debug.Log("Performing Occlusion");
//#endif
// setRTPCLoPass.SetValue(gameObject, LowPass_Max);
// setRTPCVolume.SetValue(gameObject, Volume_Max);
// }
// void PerformNoOcclusion()
// {
//#if UNITY_EDITOR
// if (DebugScript) Debug.Log("No Occlusion Performing");
//#endif
// setRTPCLoPass.SetValue(gameObject, 0);
// setRTPCVolume.SetValue(gameObject, 0);
// AkSoundEngine.SetRTPCValue("RTPC_BypassEffect", 0);
// AkSoundEngine.SetRTPCValue("RTPC_BypassEffect_Outdoor", 0);
// }
// void BypassPlugInEffectsRTPCs(bool isOccluding, string regionName)
// {
// if (isOccluding)
// {
// switch (regionName)
// {
// case "SwitchCavern":
//#if UNITY_EDITOR
// if (DebugScript) Debug.Log("Bypass RTPC called values called");
//#endif
// AkSoundEngine.SetRTPCValue("RTPC_BypassEffect", 1);
// AkSoundEngine.SetRTPCValue("RTPC_BypassEffect_Outdoor", 1);
// break;
// default:
// AkSoundEngine.SetRTPCValue("RTPC_BypassEffect", 1);
// return;
// }
// }
// else
// {
// return;
// }
// }
//}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment