1
-
1
+ using System . Collections ;
2
2
using UnityEngine ;
3
3
4
4
namespace UnityCore {
@@ -7,7 +7,179 @@ namespace Audio {
7
7
8
8
public class AudioController : MonoBehaviour
9
9
{
10
+ public static AudioController instance ;
11
+
12
+ public bool debug ;
13
+ public AudioTrack [ ] tracks ;
14
+
15
+ private Hashtable m_AudioTable ; // relationship of audio types (key) and tracks (value)
16
+ private Hashtable m_JobTable ; // relationship between audio types (key) and jobs (value)
17
+
18
+ private enum AudioAction {
19
+ START ,
20
+ STOP ,
21
+ RESTART
22
+ }
23
+
24
+ private struct AudioJob {
25
+ public AudioAction action ;
26
+ public AudioType type ;
27
+ public bool fade ;
28
+ public float delay ;
29
+
30
+ public AudioJob ( AudioAction _action , AudioType _type , bool _fade , float _delay ) {
31
+ action = _action ;
32
+ type = _type ;
33
+ fade = _fade ;
34
+ delay = _delay ;
35
+ }
36
+ }
37
+
38
+ #region Unity Functions
39
+ private void Awake ( ) {
40
+ if ( ! instance ) {
41
+ Configure ( ) ;
42
+ }
43
+ }
44
+
45
+ private void OnDisable ( ) {
46
+ Dispose ( ) ;
47
+ }
48
+ #endregion
49
+
50
+ #region Public Functions
51
+ public void PlayAudio ( AudioType _type , bool _fade = false , float _delay = 0.0F ) {
52
+ AddJob ( new AudioJob ( AudioAction . START , _type , _fade , _delay ) ) ;
<
57AE
/td>53
+ }
54
+
55
+ public void StopAudio ( AudioType _type , bool _fade = false , float _delay = 0.0F ) {
56
+ AddJob ( new AudioJob ( AudioAction . STOP , _type , _fade , _delay ) ) ;
57
+ }
58
+
59
+ public void RestartAudio ( AudioType _type , bool _fade = false , float _delay = 0.0F ) {
60
+ AddJob ( new AudioJob ( AudioAction . RESTART , _type , _fade , _delay ) ) ;
61
+ }
62
+ #endregion
63
+
64
+ #region Private Functions
65
+ private void Configure ( ) {
66
+ instance = this ;
67
+ m_AudioTable = new Hashtable ( ) ;
68
+ m_JobTable = new Hashtable ( ) ;
69
+ GenerateAudioTable ( ) ;
70
+ }
71
+
72
+ private void Dispose ( ) {
73
+ // cancel all jobs in progress
74
+ foreach ( DictionaryEntry _kvp in m_JobTable ) {
75
+ IEnumerator _job = ( IEnumerator ) _kvp . Value ;
76
+ StopCoroutine ( _job ) ;
77
+ }
78
+ }
79
+
80
+ private void AddJob ( AudioJob _job ) {
81
+ // cancel the job if one exists with the same type
82
+ if ( m_JobTable . ContainsKey ( _job . type ) ) {
83
+ Log ( "Stopping job on [" + _job . type + "] for new operation: " + _job . action ) ;
84
+ IEnumerator _runningJob = ( IEnumerator ) m_JobTable [ _job . type ] ;
85
+ StopCoroutine ( _runningJob ) ;
86
+ m_JobTable . Remove ( _job . type ) ;
87
+ }
88
+
89
+ if ( GetAudioTrack ( _job . type , _job. action . ToString ( ) ) == null ) {
90
+ return ;
91
+ }
92
+
93
+ IEnumerator _jobRunner = RunAudioJob ( _job ) ;
94
+ m_JobTable . Add ( _job . type , _jobRunner ) ;
95
+ StartCoroutine ( _jobRunner ) ;
96
+ Log ( "Starting job on [" + _job . type + "] with operation: " + _job . action ) ;
97
+ }
98
+
99
+ private IEnumerator RunAudioJob ( AudioJob _job ) {
100
+ yield return new WaitForSeconds ( _job . delay ) ;
101
+
102
+ AudioTrack _track = GetAudioTrack ( _job . type ) ; // track existence should be verified by now
103
+ _track . source . clip = GetAudioClipFromAudioTrack ( _job . type , _track ) ;
104
+
105
+ switch ( _job . action ) {
106
+ case AudioAction . START :
107
+ _track . source . Play ( ) ;
108
+ break ;
109
+ case AudioAction . STOP :
110
+ if ( ! _job . fade ) {
111
+ _track . source . Stop ( ) ;
112
+ }
113
+ break ;
114
+ case AudioAction . RESTART :
115
+ _track . source . Stop ( ) ;
116
+ _track . source . Play ( ) ;
117
+ break ;
118
+ }
119
+
120
+ // fade volume
121
+ if ( _job . fade ) {
122
+ float _initial = _job . action == AudioAction . START || _job . action == AudioAction . RESTART ? 0 : 1 ;
123
+ float _target = _initial == 0 ? 1 : 0 ;
124
+ float _duration = 1.0f ;
125
+ float _timer = 0.0f ;
126
+
127
+ while ( _timer < _duration ) {
128
+ _track . source . volume = Mathf . Lerp ( _initial , _target , _timer / _duration ) ;
129
+ _timer += Time . deltaTime ;
130
+ yield return null ;
131
+ }
132
+
133
+ if ( _job . action == AudioAction . STOP ) {
134
+ _track . source . Stop ( ) ;
135
+ }
136
+ }
137
+
138
+ m_JobTable . Remove ( _job . type ) ;
139
+ Log ( "Job count: " + m_JobTable . Count ) ;
140
+ }
141
+
142
+ private void GenerateAudioTable ( ) {
143
+ foreach ( AudioTrack _track in tracks ) {
144
+ foreach ( AudioObject _obj in _track . audio ) {
145
+ // do not duplicate keys
146
+ if ( m_AudioTable . ContainsKey ( _obj . type ) ) {
147
+ LogWarning ( "You are trying to register audio [" + _obj . type + "] that has already been registered." ) ;
148
+ } else {
149
+ m_AudioTable . Add ( _obj . type , _track ) ;
150
+ Log ( "Registering audio [" + _obj . type + "]" ) ;
151
+ }
152
+ }
153
+ }
154
+ }
155
+
156
+ private AudioTrack GetAudioTrack ( AudioType _type , string _job = "" ) {
157
+ if ( ! m_AudioTable . ContainsKey ( _type ) ) {
158
+ LogWarning ( "You are trying to <color=#fff>" + _job + "</color> for [" + _type + "] but no track was found supporting this audio type." ) ;
159
+ return null ;
160
+ }
161
+ return ( AudioTrack ) m_AudioTable [ _type ] ;
162
+ }
163
+
164
+ private AudioClip GetAudioClipFromAudioTrack ( AudioType _type , AudioTrack _track ) {
165
+ foreach ( AudioObject _obj in _track . audio ) {
166
+ if ( _obj . type == _type ) {
167
+ return _obj . clip ;
168
+ }
169
+ }
170
+ return null ;
171
+ }
172
+
173
+ private void Log ( string _msg ) {
174
+ if ( ! debug ) return ;
175
+ Debug . Log ( "[Audio Controller]: " + _msg ) ;
176
+ }
10
177
178
+ private void LogWarning ( string _msg ) {
179
+ if ( ! debug ) return ;
180
+ Debug . LogWarning ( "[Audio Controller]: " + _msg ) ;
181
+ }
182
+ #endregion
11
183
}
12
184
}
13
185
}