Skip to content

Instantly share code, notes, and snippets.

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

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

Select an option

Save athiedmann/b2833e1d9620ad67003968b4efbbc366 to your computer and use it in GitHub Desktop.
Audio object occlusion in Unity with WwiseObjectOcclusion. Fires a raycast when player enters a sphere collider range and detects if objects are between player and item. If so, occlusion is applied.
using UnityEngine;
////////////////////////////////////////////////////////////////////////
//
// Adapted and modified from the Occlusion Script from Cujo Sound video "Wwise and Unity - Basic Raycasting To Create Occlusion Parameters"
//
////////////////////////////////////////////////////////////////////////
//Uses Logger.cs, there's a commented version using the Unity Debugger wrapped in a region below
public class WwiseObjectOcclusion : MonoBehaviour
{
#if UNITY_EDITOR
public bool DebugScript = false;
#endif
public bool IsInteractable = false;
public GameObject AudioListener;
public AK.Wwise.RTPC[] OcclusionsRTPC;
public float SetLowPassMax = 1;
public float SetVolumeMax = 1;
public string NameOfListener = "CameraBrain";
public string OmitTypeOccluder; // change to array if multiple and adjust code
private bool lastOcclusionState = false;
private float maxDistanceOcclusion;
private SphereCollider sphereCollider;
private AK.Wwise.RTPC setRTPCLoPass;
private AK.Wwise.RTPC setRTPCVolume;
private void Awake()
{
if (!enabled)
{
Destroy(this);
return;
}
SetUpChecks();
sphereCollider = GetComponent<SphereCollider>();
maxDistanceOcclusion = sphereCollider.radius;
}
private void SetUpChecks()
{
if (OcclusionsRTPC.Length == 2)
{
setRTPCLoPass = OcclusionsRTPC[0];
setRTPCVolume = OcclusionsRTPC[1];
setRTPCLoPass.SetValue(gameObject, 0);
setRTPCVolume.SetValue(gameObject, 0);
}
else if (OcclusionsRTPC.Length > 2)
{
setRTPCLoPass = OcclusionsRTPC[0];
setRTPCVolume = OcclusionsRTPC[1];
setRTPCLoPass.SetValue(gameObject, 0);
setRTPCVolume.SetValue(gameObject, 0);
Logger.Log($"Remember to set up the additional RTPC's within the OcclusionCheck() function of {this.name}.");
}
else
{
Logger.LogError($"Set RTPC array with at least 2 parameters at {this.name}. Returning");
enabled = false;
return;
}
}
private void Start()
{
if (AudioListener == null || sphereCollider == null)
{
if (DebugScript)
Logger.LogError($"WwiseObjectOcclusion is returning, AudioListener or sphereCollider aren't properly set on {this.name}");
enabled = false;
return;
}
setRTPCLoPass.SetValue(gameObject, 0);
setRTPCVolume.SetValue(gameObject, 0);
AkSoundEngine.RegisterGameObj(gameObject);
}
private void FixedUpdate()
{
OcclusionCheck();
if (IsInteractable)
IsOneShotInteractable();
}
void OcclusionCheck()
{
bool currentOcclusionState = false;
Vector3 direction = AudioListener.transform.position - transform.position;
float distanceToPlayer = direction.magnitude; // Calculate the distance to the player
if (distanceToPlayer <= maxDistanceOcclusion) // Check if the player is within the occlusion range
{
if (DebugScript)
Logger.Log("Player is within range");
if (Physics.Raycast(transform.position, direction, out RaycastHit outInfo, maxDistanceOcclusion))
{
if (DebugScript)
Logger.Log(outInfo.collider.gameObject.name);
if (outInfo.collider.gameObject.name != NameOfListener && !outInfo.collider.gameObject.name.Contains(OmitTypeOccluder))
{
currentOcclusionState = true;
if (lastOcclusionState != currentOcclusionState)
{
setRTPCLoPass.SetValue(gameObject, SetLowPassMax);
setRTPCVolume.SetValue(gameObject, SetVolumeMax);
lastOcclusionState = currentOcclusionState;
if (DebugScript)
Logger.Log("Occluding");
}
}
else
{
currentOcclusionState = false;
if (lastOcclusionState != currentOcclusionState)
{
setRTPCLoPass.SetValue(gameObject, 0);
setRTPCVolume.SetValue(gameObject, 0);
lastOcclusionState = currentOcclusionState;
if (DebugScript)
Logger.Log("Not Occluding");
}
}
if (DebugScript)
Logger.Log($"lastOcclusionState is {lastOcclusionState}");
}
}
else
{
if (DebugScript)
Logger.Log($"Player is beyond {this.name} occlusion range");
if (DebugScript)
Logger.Log($"lastOcclusionState is {lastOcclusionState}");
return;
}
}
private void IsOneShotInteractable()
{
Animator objectAnimator = GetComponentInParent<Animator>();
bool animatorState = objectAnimator.GetBool("Open");
if (DebugScript)
Logger.Log($"Animator state on {this.name} is {animatorState}");
if (animatorState)
{
AkSoundEngine.UnregisterGameObj(gameObject);
Destroy(GetComponent<AkGameObj>());
Destroy(GetComponent<Rigidbody>());
Destroy(this);
}
}
}
#region UnityLogScript
//using UnityEngine;
//using Debug = UnityEngine.Debug;
////////////////////////////////////////////////////////////////////////
//
// Adapted and modified from the Occlusion Script from Cujo Sound video "Wwise and Unity - Basic Raycasting To Create Occlusion Parameters"
//
////////////////////////////////////////////////////////////////////////
////[RequireComponent(typeof(SphereCollider))]
//public class WwiseObjectOcclusion : MonoBehaviour
//{
//#if UNITY_EDITOR
// public bool DebugScript = false;
//#endif
// public bool IsInteractable = false;
// public GameObject AudioListener;
// [Tooltip("Index 0: Set LowPass. Index 1: Set Volume")]
// public AK.Wwise.RTPC[] OcclusionsRTPC;
// public float SetLowPassMax = 1;
// public float SetVolumeMax = 1;
// public string NameOfListener = "CameraBrain";
// public string OmitTypeOccluder; // change to array if multiple and adjust code
// private float maxDistanceOcclusion;
// private SphereCollider sphereCollider;
// private AK.Wwise.RTPC setRTPCLoPass;
// private AK.Wwise.RTPC setRTPCVolume;
// private void Awake()
// {
// if (!enabled)
// {
// Destroy(this);
// return;
// }
// SetUpChecks();
// sphereCollider = GetComponent<SphereCollider>();
// maxDistanceOcclusion = sphereCollider.radius;
// }
// private void SetUpChecks()
// {
// if (OcclusionsRTPC.Length == 2)
// {
// setRTPCLoPass = OcclusionsRTPC[0];
// setRTPCVolume = OcclusionsRTPC[1];
// setRTPCLoPass.SetValue(gameObject, 0);
// setRTPCVolume.SetValue(gameObject, 0);
// }
// else if (OcclusionsRTPC.Length > 2)
// {
// setRTPCLoPass = OcclusionsRTPC[0];
// setRTPCVolume = OcclusionsRTPC[1];
// setRTPCLoPass.SetValue(gameObject, 0);
// setRTPCVolume.SetValue(gameObject, 0);
//#if UNITY_EDITOR
// Debug.Log($"Remember to set up the additional RTPC's within the OcclusionCheck() function of {this.name}.");
//#endif
// }
// else
// {
//#if UNITY_EDITOR
// Debug.LogError($"Set RTPC array with at least 2 parameters at {this.name}. Returning");
//#endif
// enabled = false;
// return;
// }
// }
// private void Start()
// {
// if (AudioListener == null || sphereCollider == null)
// {
//#if UNITY_EDITOR
// if (DebugScript)
// Debug.LogError($"WwiseObjectOcclusion is returning, AudioListener or sphereCollider aren't properly set on {this.name}");
//#endif
// enabled = false;
// return;
// }
// AkSoundEngine.RegisterGameObj(gameObject);
// }
// private void FixedUpdate()
// {
// OcclusionCheck();
// if (IsInteractable)
// IsOneShotInteractable();
// }
// void OcclusionCheck()
// {
// Vector3 direction = AudioListener.transform.position - transform.position;
// float distanceToPlayer = direction.magnitude; // Calculate the distance to the player
// if (distanceToPlayer <= maxDistanceOcclusion) // Check if the player is within the occlusion range
// {
//#if UNITY_EDITOR
// if (DebugScript)
// Debug.Log("Player is within range");
//#endif
// if (Physics.Raycast(transform.position, direction, out RaycastHit outInfo, maxDistanceOcclusion))
// {
//#if UNITY_EDITOR
// if (DebugScript)
// Debug.Log(outInfo.collider.gameObject.name);
//#endif
// if (outInfo.collider.gameObject.name != NameOfListener && !outInfo.collider.gameObject.name.Contains(OmitTypeOccluder))
// {
//#if UNITY_EDITOR
// if (DebugScript)
// Debug.Log("Occluding");
//#endif
// setRTPCLoPass.SetValue(gameObject, SetLowPassMax);
// setRTPCVolume.SetValue(gameObject, SetVolumeMax);
// }
// else
// {
//#if UNITY_EDITOR
// if (DebugScript)
// Debug.Log("Not Occluding");
//#endif
// setRTPCLoPass.SetValue(gameObject, 0);
// setRTPCVolume.SetValue(gameObject, 0);
// }
// }
// }
// else
// {
//#if UNITY_EDITOR
// if (DebugScript)
// Debug.Log($"Player is beyond {this.name} occlusion range");
//#endif
// return;
// }
// }
// /// <summary>
// /// Configure to your project
// /// </summary>
// private void IsOneShotInteractable()
// {
// Animator objectAnimator = GetComponentInParent<Animator>(); //Or simply "GetComponent<Type>()"
// bool animatorState = objectAnimator.GetBool("Open");
//#if UNITY_EDITOR
// if (DebugScript)
// Debug.Log($"Animator state on {this.name} is {animatorState}");
//#endif
// if (animatorState)
// {
// Destroy(this);
// }
// }
//}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment