WKLib 0.2.3
A modding library for White Knuckle
Loading...
Searching...
No Matches
AudioManager.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using UnityEngine;
4
6
7public enum AudioMixerType
8{
9 Music,
10 Sfx,
11 UI,
12}
13
14internal class AudioManager : MonoSingleton<AudioManager>
15{
16 private Queue<AudioSource> _audioSourcePool = new();
17 private List<AudioSource> _playingSources = new();
18
19 public static void CreateAudioManager()
20 {
21 if (Instance) return;
22 Instance = new GameObject("AudioManager").AddComponent<AudioManager>();
23 }
24
25 public AudioSource PlaySound(
26 AudioClip clip,
27 Vector3 position,
28 Transform parent = null,
29 float volume = 1f,
30 float pitch = 1f,
31 bool loop = false,
32 float spatial = 1f,
33 float reverbMix = 1f,
34 bool bypassEffects = false,
35 float minDistance = 0,
36 float? maxDistance = null,
37 float? dopplerLevel = null,
38 float? spread = null,
39 AudioRolloffMode? rolloffMode = null,
40 AnimationCurve customRolloffCurve = null,
41 AudioMixerType mixerType = AudioMixerType.Sfx,
42 string sourceType = "")
43 {
44 if (!clip) return null;
45
46 if (_audioSourcePool.Count == 0)
47 CreateAudioSource();
48
49 var source = _audioSourcePool.Dequeue();
50 source.clip = clip;
51 source.transform.position = position;
52 if(parent)
53 source.transform.SetParent(parent, true);
54 source.volume = volume;
55 source.pitch = pitch;
56 source.loop = loop;
57 source.spatialBlend = spatial;
58 source.reverbZoneMix = reverbMix;
59 source.bypassEffects = bypassEffects;
60 source.minDistance = minDistance;
61
62 if (!string.IsNullOrEmpty(sourceType) && global::AudioManager.sourceTypeDict.TryGetValue(sourceType, out var audioSourceType))
63 {
64 AudioSource audioSourcePrefab = audioSourceType.audioSourcePrefab;
65 source.dopplerLevel = dopplerLevel ?? audioSourcePrefab.dopplerLevel;
66 source.spread = spread ?? audioSourcePrefab.spread;
67 source.maxDistance = maxDistance ?? audioSourcePrefab.maxDistance;
68 if (rolloffMode == null)
69 {
70 AnimationCurve customCurve = audioSourcePrefab.GetCustomCurve(AudioSourceCurveType.CustomRolloff);
71 source.rolloffMode = AudioRolloffMode.Custom;
72 source.SetCustomCurve(AudioSourceCurveType.CustomRolloff, customRolloffCurve ?? customCurve);
73 }
74 }
75 else
76 {
77 AudioSource defaultAudio = global::AudioManager.defaultAudio;
78 source.dopplerLevel = dopplerLevel ?? defaultAudio.dopplerLevel;
79 source.spread = spread ?? defaultAudio.spread;
80 source.maxDistance = maxDistance ?? defaultAudio.maxDistance;
81 if (rolloffMode == null)
82 {
83 AnimationCurve customCurve = defaultAudio.GetCustomCurve(AudioSourceCurveType.CustomRolloff);
84 source.rolloffMode = AudioRolloffMode.Custom;
85 source.SetCustomCurve(AudioSourceCurveType.CustomRolloff, customRolloffCurve ?? customCurve);
86 }
87 }
88
89 source.rolloffMode = rolloffMode ?? source.rolloffMode;
90
91 source.outputAudioMixerGroup = mixerType switch
92 {
93 AudioMixerType.Music => global::AudioManager.instance.soundtrackMixer,
94 AudioMixerType.Sfx => global::AudioManager.instance.gameMixer,
95 AudioMixerType.UI => global::AudioManager.instance.UIMixer,
96 _ => source.outputAudioMixerGroup
97 };
98
99 source.gameObject.SetActive(true);
100 _playingSources.Add(source);
101 source.Play();
102
103 return source;
104 }
105
106 private void CreateAudioSource()
107 {
108 var source = new GameObject("AudioSource").AddComponent<AudioSource>();
109 source.transform.SetParent(transform);
110 source.playOnAwake = false;
111 _audioSourcePool.Enqueue(source);
112 }
113
114 private void SendBackToPool(AudioSource source)
115 {
116 _audioSourcePool.Enqueue(source);
117 source.transform.SetParent(transform);
118 source.gameObject.SetActive(false);
119 }
120
121 private void Update()
122 {
123 for (int sourceIndex = _playingSources.Count - 1; sourceIndex >= 0; sourceIndex--)
124 {
125 var source = _playingSources[sourceIndex];
126 if (!source)
127 {
128 _playingSources.RemoveAt(sourceIndex);
129 continue;
130 }
131 if (!source.isPlaying)
132 {
133 _playingSources.RemoveAt(sourceIndex);
134 SendBackToPool(source);
135 }
136 }
137 }
138}