multiple xr toolkit package
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AutoAddSpatialAudioComponents.cs 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #define SUPPORT_DEPRECATED_ONSP
  2. using UnityEngine;
  3. using System.Collections;
  4. using UnityEditor;
  5. using VRCSDK2;
  6. [InitializeOnLoad]
  7. public class AutoAddSpatialAudioComponents
  8. {
  9. public static bool Enabled = true;
  10. static AutoAddSpatialAudioComponents()
  11. {
  12. EditorApplication.hierarchyWindowChanged += OnHierarchyWindowChanged;
  13. EditorApplication.projectWindowChanged += OnProjectWindowChanged;
  14. RegisterCallbacks();
  15. }
  16. static void OnHierarchyWindowChanged()
  17. {
  18. if (!Enabled)
  19. {
  20. EditorApplication.hierarchyWindowChanged -= OnHierarchyWindowChanged;
  21. return;
  22. }
  23. // check for proper use of VRCSP, and warn
  24. //TryToAddSpatializationToAllAudioSources(true, false);
  25. }
  26. static void OnProjectWindowChanged()
  27. {
  28. RegisterCallbacks();
  29. }
  30. static void RegisterCallbacks()
  31. {
  32. VRCSdkControlPanel._EnableSpatialization = VRCSDKControlPanel_EnableSpatialization;
  33. }
  34. // callback from VrcSdkControlPanel in dll
  35. public static void VRCSDKControlPanel_EnableSpatialization()
  36. {
  37. Debug.Log("Enabling spatialization on 3D AudioSources...");
  38. TryToAddSpatializationToAllAudioSources(false, true);
  39. }
  40. static bool ApplyDefaultSpatializationToAudioSource(AudioSource audioSrc, bool force = false)
  41. {
  42. if (audioSrc == null)
  43. return false;
  44. var vrcsp = audioSrc.gameObject.GetComponent<VRCSDK2.VRC_SpatialAudioSource>();
  45. // don't make changes if we already have a vrcsp and we aren't forcing
  46. if (vrcsp != null && !force)
  47. return false;
  48. if (force)
  49. audioSrc.spatialBlend = 1;
  50. bool initValues = force;
  51. // is audio source set to be 2D?
  52. bool is2D = audioSrc.spatialBlend == 0;
  53. #if SUPPORT_DEPRECATED_ONSP
  54. var onsp = audioSrc.GetComponent<ONSPAudioSource>();
  55. if (onsp != null)
  56. {
  57. if (vrcsp == null)
  58. {
  59. // copy the values from deprecated component
  60. vrcsp = audioSrc.gameObject.AddComponent<VRCSDK2.VRC_SpatialAudioSource>();
  61. vrcsp.Gain = onsp.Gain;
  62. vrcsp.Near = onsp.Near;
  63. vrcsp.Far = onsp.Far;
  64. vrcsp.UseAudioSourceVolumeCurve = !onsp.UseInvSqr;
  65. vrcsp.EnableSpatialization = onsp.EnableSpatialization;
  66. }
  67. // remove deprecated component
  68. Component.DestroyImmediate(onsp);
  69. }
  70. #endif
  71. if (vrcsp == null)
  72. {
  73. // no onsp and no vrcsp, so add
  74. vrcsp = audioSrc.gameObject.AddComponent<VRCSDK2.VRC_SpatialAudioSource>();
  75. if (is2D)
  76. {
  77. // this audio source was marked as 2D, leave the vrcsp disabled
  78. vrcsp.EnableSpatialization = false;
  79. }
  80. initValues = true;
  81. }
  82. audioSrc.spatialize = vrcsp.EnableSpatialization;
  83. vrcsp.enabled = true;
  84. if (initValues)
  85. {
  86. bool isAvatar = audioSrc.GetComponentInParent<VRCSDK2.VRC_AvatarDescriptor>();
  87. vrcsp.Gain = isAvatar ? VRCSDK2.AudioManagerSettings.AvatarAudioMaxGain : VRCSDK2.AudioManagerSettings.RoomAudioGain;
  88. vrcsp.Near = 0;
  89. vrcsp.Far = isAvatar ? VRCSDK2.AudioManagerSettings.AvatarAudioMaxRange : VRCSDK2.AudioManagerSettings.RoomAudioMaxRange;
  90. vrcsp.UseAudioSourceVolumeCurve = false;
  91. }
  92. return true;
  93. }
  94. public static void TryToAddSpatializationToAllAudioSources(bool newAudioSourcesOnly, bool includeInactive)
  95. {
  96. AudioSource[] allAudioSources = includeInactive ? Resources.FindObjectsOfTypeAll<AudioSource>() : Object.FindObjectsOfType<AudioSource>();
  97. foreach (AudioSource src in allAudioSources)
  98. {
  99. if (src == null || src.gameObject == null || src.gameObject.scene != UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene())
  100. {
  101. continue;
  102. }
  103. if (newAudioSourcesOnly)
  104. {
  105. if (!IsNewAudioSource(src))
  106. continue;
  107. UnityEngine.Audio.AudioMixerGroup mixer = AssetDatabase.LoadAssetAtPath<UnityEngine.Audio.AudioMixerGroup>("Assets/VRCSDK/Dependencies/OSPNative/scenes/mixers/SpatializerMixer.mixer");
  108. if (mixer != null)
  109. {
  110. src.outputAudioMixerGroup = mixer;
  111. }
  112. }
  113. if (ApplyDefaultSpatializationToAudioSource(src, false))
  114. {
  115. Debug.Log("Automatically added VRC_SpatialAudioSource component to " + GetGameObjectPath(src.gameObject) + "!");
  116. }
  117. }
  118. }
  119. static bool IsNewAudioSource(AudioSource src)
  120. {
  121. var vrcsp = src.GetComponent<VRC_SpatialAudioSource>();
  122. if (vrcsp != null)
  123. return false;
  124. if (src.clip != null)
  125. return false;
  126. if (src.outputAudioMixerGroup != null)
  127. return false;
  128. if (src.mute || src.bypassEffects || src.bypassReverbZones || !src.playOnAwake || src.loop)
  129. return false;
  130. if (src.priority != 128 ||
  131. !Mathf.Approximately(src.volume, 1.0f) ||
  132. !Mathf.Approximately(src.pitch, 1.0f) ||
  133. !Mathf.Approximately(src.panStereo, 0.0f) ||
  134. !Mathf.Approximately(src.spatialBlend, 0.0f) ||
  135. !Mathf.Approximately(src.reverbZoneMix, 1.0f))
  136. {
  137. return false;
  138. }
  139. if (!Mathf.Approximately(src.dopplerLevel, 1.0f) ||
  140. !Mathf.Approximately(src.spread, 0.0f) ||
  141. src.rolloffMode != AudioRolloffMode.Logarithmic ||
  142. !Mathf.Approximately(src.minDistance, 1.0f) ||
  143. !Mathf.Approximately(src.maxDistance, 500.0f))
  144. {
  145. return false;
  146. }
  147. return true;
  148. }
  149. static string GetGameObjectPath(GameObject obj)
  150. {
  151. string path = "/" + obj.name;
  152. while (obj.transform.parent != null)
  153. {
  154. obj = obj.transform.parent.gameObject;
  155. path = "/" + obj.name + path;
  156. }
  157. return path;
  158. }
  159. public static void ConvertONSPAudioSource(AudioSource src)
  160. {
  161. if (src == null) return;
  162. var onsp = src.GetComponent<ONSPAudioSource>();
  163. if (onsp != null)
  164. {
  165. var vrcsp = src.gameObject.GetComponent<VRCSDK2.VRC_SpatialAudioSource>();
  166. if (vrcsp == null)
  167. {
  168. // copy the values from deprecated component
  169. vrcsp = src.gameObject.AddComponent<VRCSDK2.VRC_SpatialAudioSource>();
  170. vrcsp.Gain = onsp.Gain;
  171. vrcsp.Near = onsp.Near;
  172. vrcsp.Far = onsp.Far;
  173. vrcsp.UseAudioSourceVolumeCurve = !onsp.UseInvSqr;
  174. vrcsp.EnableSpatialization = onsp.EnableSpatialization;
  175. }
  176. // remove deprecated component
  177. Component.DestroyImmediate(onsp);
  178. }
  179. }
  180. public static void AddVRCSpatialToBareAudioSource(AudioSource src)
  181. {
  182. if (src == null) return;
  183. var vrcsp = src.gameObject.GetComponent<VRCSDK2.VRC_SpatialAudioSource>();
  184. if (vrcsp != null) return;
  185. vrcsp = src.gameObject.AddComponent<VRCSDK2.VRC_SpatialAudioSource>();
  186. // add default values
  187. bool isAvatar = src.gameObject.GetComponentInParent<VRCSDK2.VRC_AvatarDescriptor>();
  188. vrcsp.Gain = isAvatar ? VRCSDK2.AudioManagerSettings.AvatarAudioMaxGain : VRCSDK2.AudioManagerSettings.RoomAudioGain;
  189. vrcsp.Near = 0;
  190. vrcsp.Far = isAvatar ? VRCSDK2.AudioManagerSettings.AvatarAudioMaxRange : VRCSDK2.AudioManagerSettings.RoomAudioMaxRange;
  191. vrcsp.UseAudioSourceVolumeCurve = false;
  192. // enable spatialization if src is not 2D
  193. AnimationCurve curve = src.GetCustomCurve(AudioSourceCurveType.SpatialBlend);
  194. if (src.spatialBlend == 0 || (curve == null || curve.keys.Length <= 1))
  195. vrcsp.EnableSpatialization = false;
  196. else
  197. vrcsp.EnableSpatialization = true;
  198. }
  199. }