SoundFX.cs
9.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
using UnityEngine;
using UnityEngine.Audio;
namespace OVR
{
public enum SoundFXNext {
Random = 0,
Sequential = 1,
}
public enum FreqHint {
None = 0,
Wide = 1,
Narrow = 2,
}
public enum SoundPriority {
VeryLow = -2,
Low = -1,
Default = 0,
High = 1,
VeryHigh = 2,
}
[System.Serializable]
public class OSPProps {
public OSPProps() {
enableSpatialization = false;
useFastOverride = false;
gain = 0.0f;
enableInvSquare = false;
volumetric = 0.0f;
invSquareFalloff = new Vector2( 1.0f, 25.0f );
}
[Tooltip( "Set to true to play the sound FX spatialized with binaural HRTF, default = false")]
public bool enableSpatialization = false;
[Tooltip( "Play the sound FX with reflections, default = false")]
public bool useFastOverride = false;
[Tooltip( "Boost the gain on the spatialized sound FX, default = 0.0")]
[Range( 0.0f, 24.0f )]
public float gain = 0.0f;
[Tooltip("Enable Inverse Square attenuation curve, default = false")]
public bool enableInvSquare = false;
[Tooltip("Change the sound from point source (0.0f) to a spherical volume, default = 0.0")]
[Range(0.0f, 1000.0f)]
public float volumetric = 0.0f;
[Tooltip("Set the near and far falloff value for the OSP attenuation curve, default = 1.0")]
[MinMax ( 1.0f, 25.0f, 0.0f, 250.0f )]
public Vector2 invSquareFalloff = new Vector2( 1.0f, 25.0f );
}
/*
-----------------------
SoundFX
-----------------------
*/
[System.Serializable]
public class SoundFX {
public SoundFX() {
playback = SoundFXNext.Random;
volume = 1.0f;
pitchVariance = Vector2.one;
falloffDistance = new Vector2( 1.0f, 25.0f );
falloffCurve = AudioRolloffMode.Linear;
volumeFalloffCurve = new AnimationCurve( new Keyframe[2] { new Keyframe( 0f, 1.0f ), new Keyframe( 1f, 1f ) } );
reverbZoneMix = new AnimationCurve( new Keyframe[2] { new Keyframe( 0f, 1.0f ), new Keyframe( 1f, 1f ) } );
spread = 0.0f;
pctChanceToPlay = 1.0f;
priority = SoundPriority.Default;
delay = Vector2.zero;
looping = false;
ospProps = new OSPProps();
}
[Tooltip( "Each sound FX should have a unique name")]
public string name = string.Empty;
[Tooltip( "Sound diversity playback option when multiple audio clips are defined, default = Random")]
public SoundFXNext playback = SoundFXNext.Random;
[Tooltip( "Default volume for this sound FX, default = 1.0")]
[Range (0.0f, 1.0f)]
public float volume = 1.0f;
[Tooltip( "Random pitch variance each time a sound FX is played, default = 1.0 (none)")]
[MinMax ( 1.0f, 1.0f, 0.0f, 2.0f )]
public Vector2 pitchVariance = Vector2.one;
[Tooltip( "Falloff distance for the sound FX, default = 1m min to 25m max")]
[MinMax ( 1.0f, 25.0f, 0.0f, 250.0f )]
public Vector2 falloffDistance = new Vector2( 1.0f, 25.0f );
[Tooltip( "Volume falloff curve - sets how the sound FX attenuates over distance, default = Linear")]
public AudioRolloffMode falloffCurve = AudioRolloffMode.Linear;
[Tooltip( "Defines the custom volume falloff curve")]
public AnimationCurve volumeFalloffCurve = new AnimationCurve( new Keyframe[2] { new Keyframe( 0f, 1.0f ), new Keyframe( 1f, 1f ) } );
[Tooltip( "The amount by which the signal from the AudioSource will be mixed into the global reverb associated with the Reverb Zones | Valid range is 0.0 - 1.1, default = 1.0" )]
public AnimationCurve reverbZoneMix = new AnimationCurve( new Keyframe[2] { new Keyframe( 0f, 1.0f ), new Keyframe( 1f, 1f ) } );
[Tooltip( "Sets the spread angle (in degrees) of a 3d stereo or multichannel sound in speaker space, default = 0")]
[Range (0.0f, 360.0f)]
public float spread = 0.0f;
[Tooltip( "The percentage chance that this sound FX will play | 0.0 = none, 1.0 = 100%, default = 1.0")]
[Range (0.0f, 1.0f)]
public float pctChanceToPlay = 1.0f;
[Tooltip( "Sets the priority for this sound to play and/or to override a currently playing sound FX, default = Default")]
public SoundPriority priority = SoundPriority.Default;
[Tooltip( "Specifies the default delay when this sound FX is played, default = 0.0 secs")]
[MinMax ( 0.0f, 0.0f, 0.0f, 2.0f )]
public Vector2 delay = Vector2.zero; // this overrides any delay passed into PlaySound() or PlaySoundAt()
[Tooltip( "Set to true for the sound to loop continuously, default = false")]
public bool looping = false;
public OSPProps ospProps = new OSPProps();
[Tooltip( "List of the audio clips assigned to this sound FX")]
public AudioClip[] soundClips = new AudioClip[1];
// editor only - unfortunately if we set it not to serialize, we can't query it from the editor
public bool visibilityToggle = false;
// runtime vars
[System.NonSerialized]
private SoundGroup soundGroup = null;
private int lastIdx = -1;
private int playingIdx = -1;
public int Length { get { return soundClips.Length; } }
public bool IsValid { get { return ( ( soundClips.Length != 0 ) && ( soundClips[0] != null ) ); } }
public SoundGroup Group { get { return soundGroup; } set { soundGroup = value; } }
public float MaxFalloffDistSquared { get { return falloffDistance.y * falloffDistance.y; } }
public float GroupVolumeOverride { get { return ( soundGroup != null ) ? soundGroup.volumeOverride : 1.0f; } }
/*
-----------------------
GetClip()
-----------------------
*/
public AudioClip GetClip() {
if ( soundClips.Length == 0 ) {
return null;
} else if ( soundClips.Length == 1 ) {
return soundClips[0];
}
if ( playback == SoundFXNext.Random ) {
// random, but don't pick the last one
int idx = Random.Range( 0, soundClips.Length );
while ( idx == lastIdx ) {
idx = Random.Range( 0, soundClips.Length );
}
lastIdx = idx;
return soundClips[idx];
} else {
// sequential
if ( ++lastIdx >= soundClips.Length ) {
lastIdx = 0;
}
return soundClips[lastIdx];
}
}
/*
-----------------------
GetMixerGroup()
-----------------------
*/
public AudioMixerGroup GetMixerGroup( AudioMixerGroup defaultMixerGroup ) {
if ( soundGroup != null ) {
return ( soundGroup.mixerGroup != null ) ? soundGroup.mixerGroup : defaultMixerGroup;
}
return defaultMixerGroup;
}
/*
-----------------------
ReachedGroupPlayLimit()
-----------------------
*/
public bool ReachedGroupPlayLimit() {
if ( soundGroup != null ) {
return !soundGroup.CanPlaySound();
}
return false;
}
/*
-----------------------
GetClipLength()
-----------------------
*/
public float GetClipLength( int idx ) {
if ( ( idx == -1 ) || ( soundClips.Length == 0 ) || ( idx >= soundClips.Length ) || ( soundClips[idx] == null ) ) {
return 0.0f;
} else {
return soundClips[idx].length;
}
}
/*
-----------------------
GetPitch()
-----------------------
*/
public float GetPitch() {
return Random.Range( pitchVariance.x, pitchVariance.y );
}
/*
-----------------------
PlaySound()
-----------------------
*/
public int PlaySound( float delaySecs = 0.0f ) {
playingIdx = -1;
if ( !IsValid ) {
return playingIdx;
}
// check the random chance to play here to save the function calls
if ( ( pctChanceToPlay > 0.99f ) || ( Random.value < pctChanceToPlay ) ) {
if ( delay.y > 0.0f ) {
delaySecs = Random.Range( delay.x, delay.y );
}
playingIdx = AudioManager.PlaySound( this, EmitterChannel.Any, delaySecs );
}
return playingIdx;
}
/*
-----------------------
PlaySoundAt()
-----------------------
*/
public int PlaySoundAt( Vector3 pos, float delaySecs = 0.0f, float volumeOverride = 1.0f, float pitchMultiplier = 1.0f ) {
playingIdx = -1;
if ( !IsValid ) {
return playingIdx;
}
// check the random chance to play here to save the function calls
if ( ( pctChanceToPlay > 0.99f ) || ( Random.value < pctChanceToPlay ) ) {
if ( delay.y > 0.0f ) {
delaySecs = Random.Range( delay.x, delay.y );
}
playingIdx = AudioManager.PlaySoundAt( pos, this, EmitterChannel.Any, delaySecs, volumeOverride, pitchMultiplier );
}
return playingIdx;
}
/*
-----------------------
SetOnFinished()
get a callback when the sound is finished playing
-----------------------
*/
public void SetOnFinished( System.Action onFinished ) {
if ( playingIdx > -1 ) {
AudioManager.SetOnFinished( playingIdx, onFinished );
}
}
/*
-----------------------
SetOnFinished()
get a callback with an object parameter when the sound is finished playing
-----------------------
*/
public void SetOnFinished( System.Action<object> onFinished, object obj ) {
if ( playingIdx > -1 ) {
AudioManager.SetOnFinished( playingIdx, onFinished, obj );
}
}
/*
-----------------------
StopSound()
-----------------------
*/
public bool StopSound() {
bool stopped = false;
if (playingIdx > -1){
stopped = AudioManager.StopSound(playingIdx);
playingIdx = -1;
}
return stopped;
}
/*
-----------------------
AttachToParent()
-----------------------
*/
public void AttachToParent( Transform parent) {
if (playingIdx > -1) {
AudioManager.AttachSoundToParent(playingIdx, parent);
}
}
/*
-----------------------
DetachFromParent()
-----------------------
*/
public void DetachFromParent() {
if (playingIdx > -1) {
AudioManager.DetachSoundFromParent(playingIdx);
}
}
}
} // namespace OVR