Created
October 3, 2023 22:15
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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