IMHOTEP Framework
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Pages
PlaySound.cs
1 //======= Copyright (c) Valve Corporation, All rights reserved. ===============
2 //
3 // Purpose: Plays one of many audio files with possible randomized parameters
4 //
5 //=============================================================================
6 
7 using UnityEngine;
8 using System.Collections;
9 
10 namespace Valve.VR.InteractionSystem
11 {
12  //-------------------------------------------------------------------------
13  [RequireComponent( typeof( AudioSource ) )]
14  public class PlaySound : MonoBehaviour
15  {
16  [Tooltip( "List of audio clips to play." )]
17  public AudioClip[] waveFile;
18  [Tooltip( "Stops the currently playing clip in the audioSource. Otherwise clips will overlap/mix." )]
19  public bool stopOnPlay;
20  [Tooltip( "After the audio clip finishes playing, disable the game object the sound is on." )]
21  public bool disableOnEnd;
22  [Tooltip( "Loop the sound after the wave file variation has been chosen." )]
23  public bool looping;
24  [Tooltip( "If the sound is looping and updating it's position every frame, stop the sound at the end of the wav/clip length. " )]
25  public bool stopOnEnd;
26  [Tooltip( "Start a wave file playing on awake, but after a delay." )]
27  public bool playOnAwakeWithDelay;
28 
29  [Header ( "Random Volume" )]
30  public bool useRandomVolume = true;
31  [Tooltip( "Minimum volume that will be used when randomly set." )]
32  [Range( 0.0f, 1.0f )]
33  public float volMin = 1.0f;
34  [Tooltip( "Maximum volume that will be used when randomly set." )]
35  [Range( 0.0f, 1.0f )]
36  public float volMax = 1.0f;
37 
38  [Header ( "Random Pitch" )]
39  [Tooltip( "Use min and max random pitch levels when playing sounds." )]
40  public bool useRandomPitch = true;
41  [Tooltip( "Minimum pitch that will be used when randomly set." )]
42  [Range( -3.0f, 3.0f )]
43  public float pitchMin = 1.0f;
44  [Tooltip( "Maximum pitch that will be used when randomly set." )]
45  [Range( -3.0f, 3.0f )]
46  public float pitchMax = 1.0f;
47 
48  [Header( "Random Time" )]
49  [Tooltip( "Use Retrigger Time to repeat the sound within a time range" )]
50  public bool useRetriggerTime = false;
51  [Tooltip( "Inital time before the first repetion starts" )]
52  [Range( 0.0f, 360.0f )]
53  public float timeInitial = 0.0f;
54  [Tooltip( "Minimum time that will pass before the sound is retriggered" )]
55  [Range( 0.0f, 360.0f )]
56  public float timeMin = 0.0f;
57  [Tooltip( "Maximum pitch that will be used when randomly set." )]
58  [Range( 0.0f, 360.0f )]
59  public float timeMax = 0.0f;
60 
61  [Header ( "Random Silence" )]
62  [Tooltip( "Use Retrigger Time to repeat the sound within a time range" )]
63  public bool useRandomSilence = false;
64  [Tooltip( "Percent chance that the wave file will not play" )]
65  [Range( 0.0f, 1.0f )]
66  public float percentToNotPlay = 0.0f;
67 
68  [Header( "Delay Time" )]
69  [Tooltip( "Time to offset playback of sound" )]
70  public float delayOffsetTime = 0.0f;
71 
72 
73  private AudioSource audioSource;
74  private AudioClip clip;
75 
76  //-------------------------------------------------
77  void Awake()
78  {
79  audioSource = GetComponent<AudioSource>();
80  clip = audioSource.clip;
81 
82  // audio source play on awake is true, just play the PlaySound immediately
83  if ( audioSource.playOnAwake )
84  {
85  if ( useRetriggerTime )
86  InvokeRepeating( "Play", timeInitial, Random.Range( timeMin, timeMax ) );
87  else
88  Play();
89  }
90 
91  // if playOnAwake is false, but the playOnAwakeWithDelay on the PlaySound is true, play the sound on away but with a delay
92  else if ( !audioSource.playOnAwake && playOnAwakeWithDelay )
93  {
94  PlayWithDelay( delayOffsetTime );
95 
96  if ( useRetriggerTime )
97  InvokeRepeating( "Play", timeInitial, Random.Range( timeMin, timeMax ) );
98  }
99 
100  // in the case where both playOnAwake and playOnAwakeWithDelay are both set to true, just to the same as above, play the sound but with a delay
101  else if ( audioSource.playOnAwake && playOnAwakeWithDelay )
102  {
103  PlayWithDelay( delayOffsetTime );
104 
105  if ( useRetriggerTime )
106  InvokeRepeating( "Play", timeInitial, Random.Range( timeMin, timeMax ) );
107  }
108  }
109 
110 
111  //-------------------------------------------------
112  // Play a random clip from those available
113  //-------------------------------------------------
114  public void Play()
115  {
116  if ( looping )
117  {
118  PlayLooping();
119 
120  }
121 
122  else PlayOneShotSound();
123  }
124 
125 
126  //-------------------------------------------------
127  public void PlayWithDelay( float delayTime )
128  {
129  if ( looping )
130  Invoke( "PlayLooping", delayTime );
131  else
132  Invoke( "PlayOneShotSound", delayTime );
133  }
134 
135 
136  //-------------------------------------------------
137  // Play random wave clip on audiosource as a one shot
138  //-------------------------------------------------
139  public AudioClip PlayOneShotSound()
140  {
141  if ( !this.audioSource.isActiveAndEnabled )
142  return null;
143 
144  SetAudioSource();
145  if ( this.stopOnPlay )
146  audioSource.Stop();
147  if ( this.disableOnEnd )
148  Invoke( "Disable", clip.length );
149  this.audioSource.PlayOneShot( this.clip );
150  return this.clip;
151  }
152 
153 
154  //-------------------------------------------------
155  public AudioClip PlayLooping()
156  {
157  // get audio source properties, and do any special randomizations
158  SetAudioSource();
159 
160  // if the audio source has forgotten to be set to looping, set it to looping
161  if ( !audioSource.loop )
162  audioSource.loop = true;
163 
164  // play the clip in the audio source, all the meanwhile updating it's location
165  this.audioSource.Play();
166 
167  // if disable on end is checked, stop playing the wave file after the first loop has finished.
168  if ( stopOnEnd )
169  Invoke( "Stop", audioSource.clip.length );
170  return this.clip;
171  }
172 
173 
174  //-------------------------------------------------
175  public void Disable()
176  {
177  gameObject.SetActive( false );
178  }
179 
180 
181  //-------------------------------------------------
182  public void Stop()
183  {
184  audioSource.Stop();
185  }
186 
187 
188  //-------------------------------------------------
189  private void SetAudioSource()
190  {
191  if ( this.useRandomVolume )
192  {
193  //randomly apply a volume between the volume min max
194  this.audioSource.volume = Random.Range( this.volMin, this.volMax );
195 
196  if ( useRandomSilence && ( Random.Range( 0, 1 ) < percentToNotPlay ) )
197  {
198  this.audioSource.volume = 0;
199  }
200  }
201 
202  if ( this.useRandomPitch )
203  {
204  //randomly apply a pitch between the pitch min max
205  this.audioSource.pitch = Random.Range( this.pitchMin, this.pitchMax );
206  }
207 
208  if ( this.waveFile.Length > 0 )
209  {
210  // randomly assign a wave file from the array into the audioSource clip property
211  audioSource.clip = this.waveFile[Random.Range( 0, waveFile.Length )];
212  clip = audioSource.clip;
213  }
214  }
215  }
216 }