using UnityEngine;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
///
/// Sound manager for Tearable World. Uses AudioSources and attaches them to one object.
/// Has all of the basic controls and allows for two types, SFX and MUSIC.
///
/// Created by Douglas Weller - 2/1/13-present
///
public class SoundManager : MonoBehaviour {
#region Variables
#region Sound Variables
///
/// A pre-declared audiosource, so you don't have to declare one throughout the code
/// constantly.
///
AudioSource audioSourceTemp;
//list of sounds fading in and out
private List fadeInSounds;
private List fadeOutSounds;
///
/// Dictionary filled with the music audiosources, so you
/// can look for and play it based on the string of the sound name
///
private Dictionary myMusicSounds;
///
/// Dictionary filled with the sfx audiosources, so you
/// can look for and play it based on the string of the sound name ///
private Dictionary mySFXSounds;
///
/// The next open musicSounds array point.
///
private int musicLength = 0;
///
/// The next open point in array of SFX.
///
private int sfxLength = 0;
///
/// This is the current music vol.
///
public float musicVol = 1.0f;
///
/// This is the current sfx vol.
///
public float sfxVol = 1.0f;
///
/// List of sfx clips that have already been added, used when
/// you call LoadAudioAssets.
///
List alreadyHereSFXClips;
///
/// List of music clips that have already been added, used when
/// you call LoadAudioAssets.
///
List alreadyHereMusicClips;
// private AnimationManager animManagerRef;
// private InputManager inputManagerRef;
// private GameStateManager gameStateManagerRef;
// private TWCharacterController controllerRef;
#endregion
#endregion
#region Basic Functions
// Use this for initialization
void Start ()
{
//DontDestroyOnLoad(gameObject);
}
// Update is called once per frame
void Awake() {
if(gameObject.GetComponent() == null)
gameObject.AddComponent();
myMusicSounds = new Dictionary();
mySFXSounds = new Dictionary();
fadeInSounds = new List();
fadeOutSounds = new List();
alreadyHereSFXClips = new List();
alreadyHereMusicClips = new List();
}
void Update () {
//All fade code written by Justin Telmo, team member.
if (fadeOutSounds.Count > 0)
{
UnityEngine.Debug.Log(fadeOutSounds.First().name);
foreach (AudioSource audio in fadeOutSounds)
{
if (audio.volume > 0.1)
{
audio.volume -= 0.1f * Time.deltaTime;
}
}
}
if (fadeInSounds.Count > 0)
{
foreach (AudioSource audio in fadeInSounds)
{
while (audio.volume < 1)
{
audio.volume += 0.1f * Time.deltaTime;
}
}
}
}
#endregion
#region Load
///
/// Load all sounds in music and sfx folders to empty sfx and music arrays
/// as audioclips, then declare size of audiosource arrays for
/// music and sfx based on amount of audio pulled
///
public void LoadAllAudioAssets()
{
List tempClips = Resources.LoadAll ("Audio/Music", typeof(AudioClip)).Cast().ToList();
foreach(AudioClip ac in tempClips)
AddMusicSound(ac);
tempClips = Resources.LoadAll ("Audio/SFX", typeof(AudioClip)).Cast().ToList();
foreach(AudioClip ac in tempClips)
AddSFXSound(ac);
}
///
/// Loads the the list of given strings for music and sfx
///
///
/// List of string names of songs to be loaded
///
///
/// List of SFX names to be loaded
///
public void LoadAudioAssets(List musList, List sfxList)
{
AudioClip audioClipTemp;
RemoveSounds(musList, sfxList);
foreach(string s in musList)
{
if(!alreadyHereMusicClips.Contains(s))
{
audioClipTemp = Resources.Load("Audio/Music/"+s, typeof(AudioClip)) as AudioClip;
if(audioClipTemp)
{
AddMusicSound(audioClipTemp);
}
}
}
foreach(string s in sfxList)
{
if(!alreadyHereSFXClips.Contains(s))
{
audioClipTemp = Resources.Load("Audio/SFX/"+s, typeof(AudioClip)) as AudioClip;
if(audioClipTemp)
{
AddSFXSound(audioClipTemp);
}
}
}
audioClipTemp = null;
audioSourceTemp = null;
alreadyHereSFXClips.Clear();
alreadyHereMusicClips.Clear();
Resources.UnloadUnusedAssets();
}
private void RemoveSounds(List musList, List sfxList)
{
alreadyHereSFXClips.Clear();
alreadyHereMusicClips.Clear();
//list of the names of audioclips to be removed from current music and sfx lists
List toRemove = new List();
//look through each sound name in myMusicSounds
//and determine whether it should stay or not
//This is both to find music that is already there
//as well as dealing with songs that aren't in the list of
//new songs that need to be removed
foreach(string cn in myMusicSounds.Keys)
{
bool chosen = false;
for(int i = 0; i < musList.Count; i++)
if(cn == musList[i]) chosen = true;
if(!chosen) toRemove.Add(cn);
else alreadyHereMusicClips.Add(cn);
}
//now look through the sounds to remove, and
//double check that it in fact exists in the music list
//then remove it
foreach(string sndName in toRemove)
{
//checks that the sound is there
if(myMusicSounds.TryGetValue(sndName, out audioSourceTemp))
{
audioSourceTemp.Stop(); //stops the sound
fadeInSounds.Remove(audioSourceTemp); //begins removing references to it
myMusicSounds.Remove(sndName);
Destroy(audioSourceTemp);//destroy the object audiosource
}
}
//clear the list to check for sfx
toRemove.Clear();
//look through each sound name in mySFXSounds
//and determine whether it should stay or not
foreach(string cn in mySFXSounds.Keys)
{
bool chosen = false;
for(int i = 0; i < sfxList.Count; i++)
if(cn == sfxList[i]) chosen = true;
if(!chosen) toRemove.Add(cn);
else alreadyHereSFXClips.Add(cn);
}
//now look through the sounds to remove, and
//double check that it in fact exists in the music list
//then remove it
foreach(string sdName in toRemove)
{
if(mySFXSounds.TryGetValue(sdName, out audioSourceTemp))
{
//Debug.Log(audioSourceTemp.clip.name);
audioSourceTemp.Stop();
fadeInSounds.Remove(audioSourceTemp);
mySFXSounds.Remove(sdName);
Destroy(audioSourceTemp); //destroy the object audiosource
}
}
}
#endregion
#region Add Sounds
///
/// Adds the AudioClip given to the AudioSource array based on type.
/// Type is either "MUSIC" or "SFX"
///
///
///
/// The clip to be added to list of music audiosources
///
///
/// Type.
///
private void AddMusicSound(AudioClip clip)
{
if(!myMusicSounds.ContainsKey(clip.name))//double check the sound hasn't already been added
{
AudioSource temp;
temp = gameObject.AddComponent(); //add an audiosource to main game object
temp.name = clip.name; //make name of audio source same as the clip
temp.clip = clip; //set clip
temp.volume = musicVol; //set the volume to whatever musicvol currently is
temp.loop = true; //makes the music loop
myMusicSounds.Add(clip.name, temp);
}
}
private void AddSFXSound(AudioClip clip)
{
if(!mySFXSounds.ContainsKey(clip.name))
{
AudioSource temp;
temp = gameObject.AddComponent();//add an audiosource to main game object
temp.clip = clip; //set clip
temp.volume = sfxVol; //make the sfx set to the current sfx vol
temp.loop = false; //makes the sfx not loop
temp.name = clip.name;//make name of audio source same as the clip
mySFXSounds.Add(clip.name, temp);
}
}
#endregion
#region Volume
///
/// Checks the type of sound "SFX" or "MUSIC".
/// sndName is the name of the clip you want to stop.
/// It then calls SetVolForSpecificSnd.
///
///
/// Vol.
///
///
/// Snd name.
///
///
/// Type.
///
public void SetSpecificSoundVol(float vol, string sndName)
{
//checks if the sound is in music list
if (myMusicSounds.TryGetValue(sndName, out audioSourceTemp))
{
audioSourceTemp.volume = vol; //if it is it set it to a new vol.
return;
}
else //otherwise it checks the sfx sounds
{
if (mySFXSounds.TryGetValue(sndName, out audioSourceTemp))
{
audioSourceTemp.volume = vol; //if sounds there it set it to new vol.
return;
}
}
//well send out error if the sound isn't there, but it won't stop the game from running
Debug.LogError("No Music Sound Called " + sndName + " found.");
}
///
/// Sets the SFX vol.
///
///
/// Vol.
///
public void SetSFXVol(float vol)
{
sfxVol = vol; //set SFX vol for all new sfx added.
foreach (AudioSource m in mySFXSounds.Values)
m.volume = vol;
}
///
/// Sets the music vol.
///
///
/// Vol.
///
public void SetMusicVol(float vol)
{
musicVol = vol;//set music vol for all new music added
//loop through music and set volume for each one to vol
foreach(AudioSource m in myMusicSounds.Values)
m.volume = vol;
}
///
/// Returns the current music volume.
///
///
/// The current music volume.
///
public float GetMusicVol()
{
return musicVol;
}
///
/// Returns the current sound effects volume.
///
///
/// The current sound effects voluem.
///
public float GetSFXVol()
{
return sfxVol;
}
#region Mute
///
/// Mutes all sounds.
///
///
/// The all.
///
public void MuteAll()
{
//sfxSound.mute = true;
//for(int i = 0; i < sfxLength; i++)
// sfxSound[i].mute = true;
foreach(AudioSource m in myMusicSounds.Values)
m.mute = true;
foreach(AudioSource m in mySFXSounds.Values)
m.mute = true;
}
///
/// Unmutes all the sounds.
///
///
/// The mute all.
///
public void UnMuteAll()
{
//sfxSound.mute = false;
//for(int i = 0; i < sfxLength; i++)
// sfxSound[i].mute = false;
foreach(AudioSource m in myMusicSounds.Values)
m.mute = false;
foreach(AudioSource m in mySFXSounds.Values)
m.mute = false;
}
#endregion
#endregion
#region Stop, Pause, Play
#region Play
///
/// Plays specified audiosource
/// Needs to know type, either "MUSIC" or "SFX"
///
///
/// Source.
///
public void PlayAudio(string sndName, string type)
{
if(type == "MUSIC")//checks if its a music clip we want to play
{
if(myMusicSounds.TryGetValue(sndName, out audioSourceTemp))
{
audioSourceTemp.Play(); // if it exists play it
return;
}
}
else if(type == "SFX")//checks if its a music clip we want to play
{
if(mySFXSounds.TryGetValue(sndName, out audioSourceTemp))
{
audioSourceTemp.Play();// if it exists play it
return;
}
}
//log error if the song doesn't exist in the specified area
Debug.Log ("Failed to play " + sndName + " of type: " + type);
}
///
/// Plays an audio clip and throws it out there for
/// a one-time use. This means that the sound can be played
/// multiple times without worrying about it stopping the previous version.
/// THe problem is you can't control it anymore, so the sound will play until
/// it ends (which for music is never).
///
///
///
public void PlayAudioOneShot(string sndName, string type)
{
if(type == "SFX")
{
if(mySFXSounds.TryGetValue(sndName, out audioSourceTemp))
{
audioSourceTemp.PlayOneShot(audioSourceTemp.clip);
return;
}
}
else if(type == "MUSIC")
{
if(myMusicSounds.TryGetValue(sndName, out audioSourceTemp))
{
audioSourceTemp.PlayOneShot(audioSourceTemp.clip);
return;
}
}
Debug.Log ("Failed to play one shot " + sndName + " of type: " + type);
}
///
/// Determines whether this sound is playing currently
///
///
/// The name of the sound we want to check
///
///
/// String of type "SFX" or "MUSIC"
///
public bool IsAudioPlaying(string sndName, string type)
{
//UnityEngine.Debug.Log("Calling isAudioPlaying");
if (type == "MUSIC")
{
if(myMusicSounds.TryGetValue(sndName, out audioSourceTemp))
{
if(audioSourceTemp.isPlaying) return true;
else return false;
}
}
else if (type == "SFX")
{
if (mySFXSounds.TryGetValue(sndName, out audioSourceTemp))
{
if (audioSourceTemp.isPlaying) return true;
else return false;
}
}
return false;
}
#endregion
#region Stop
///
/// Stops specific sound, determined by AudioSource
/// Needs to know type, either "MUSIC" or "SFX"
/// Stop means that the music is stopped. When you play it again it will start from the beginning.
///
///
/// Source.
///
public void StopSound(string sndName, string type)//change string sndname to audiosource source if reverting to old code
{
if(type == "MUSIC")
{
if(myMusicSounds.TryGetValue(sndName, out audioSourceTemp))
{
audioSourceTemp.Stop();
return;
}
}
else if(type == "SFX")
{
if(mySFXSounds.TryGetValue(sndName, out audioSourceTemp))
{
UnityEngine.Debug.Log("We stopped: " + sndName);
audioSourceTemp.Stop();
return;
}
//Debug.LogError("cannot stop sfx");
return;
}
Debug.LogError("SoundManager: " + sndName + " sound not located for StopSound of type " +type);
}
///
/// Stops all sounds, so when sound plays again it will start from beginning.
///
public void StopAll()
{
foreach(AudioSource m in myMusicSounds.Values)
m.Stop();
foreach (AudioSource m in mySFXSounds.Values)
m.Stop();
}
#endregion
#region Pause
///
/// Pauses specific sound, determined by AudioSource. Needs to know type
/// either "MUSIC" or "SFX"
/// Pause means that after being paused, the song will continue from that point
/// when played again.
///
///
/// Source.
///
public void PauseSound(string sndName, string type)//change string sndname to audiosource source if reverting to old code
{
if(type == "MUSIC")
{
if(myMusicSounds.TryGetValue(sndName, out audioSourceTemp))
{
audioSourceTemp.Pause();
return;
}
}
else if(type == "SFX")
{
if (mySFXSounds.TryGetValue(sndName, out audioSourceTemp))
{
audioSourceTemp.Pause();
return;
}
return;
}
Debug.LogError("SoundManager: " + sndName + " sound not located for PauseSound of type " + type);
}
///
/// Pauses all music in musicSounds, so when music play they will begin from where they were paused.
///
public void PauseAllSounds()
{
foreach(AudioSource m in myMusicSounds.Values)
m.Pause();
foreach (AudioSource m in mySFXSounds.Values)
m.Pause();
//Debug.Log ("SoundManager: all music paused");
}
#endregion
#region Fades
///
/// Fades a given sound effect or song out.
/// Created by Justin Telmo, team member
///
///
///
public void FadeOut(string sndName, string type)
{
if (type == "MUSIC")
{
if (myMusicSounds.TryGetValue(sndName, out audioSourceTemp))
{
fadeOutSounds.Add(audioSourceTemp);
}
}
if (type == "SFX")
{
if (mySFXSounds.TryGetValue(sndName, out audioSourceTemp))
{
fadeOutSounds.Add(audioSourceTemp);
}
}
Debug.Log("Failed to begin fadeout of " + sndName + " of type " + type);
}
///
/// Fades a given sound effect or song in from zero.
/// made by justin telmo, team member
///
///
///
public void FadeIn(string sndName, string type)
{
if (type == "MUSIC")
{
if (myMusicSounds.TryGetValue(sndName, out audioSourceTemp))
{
fadeInSounds.Add(audioSourceTemp);
}
}
if (type == "SFX")
{
if (mySFXSounds.TryGetValue(sndName, out audioSourceTemp))
{
fadeInSounds.Add(audioSourceTemp);
}
}
Debug.Log("Failed to begin fadein of " + sndName + " of type " + type);
}
#endregion
#endregion
#region Pitch
///
/// This sets the pitch for a specific sound.
/// Pitch is the speed at which the sound plays, so 1 is regular, 2 is double, .5 is half.
/// The sndName is the clip name you want to change.
/// Types are "MUSIC" or "SFX"
///
public void SetSndPitch(string sndName, float pitch, string type)
{
//check type
if(type == "MUSIC")
{
if(myMusicSounds.TryGetValue(sndName, out audioSourceTemp))
{
audioSourceTemp.pitch = pitch;
return;
}
}
//check type
else if(type == "SFX")
{
if (mySFXSounds.TryGetValue(sndName, out audioSourceTemp))
{
audioSourceTemp.pitch = pitch;
return;
}
return;
}
Debug.LogError("error setting pitch of " +sndName+ " of type " + type);
}
///
/// Returns the pitch of the clip that has the same name as sndName, that is in type "MUSIC" or "SFX"
/// Pitch is the speed at which the sound plays, so 1 is regular, 2 is double, .5 is half.
///
///
/// The snd pitch.
///
///
/// Snd name.
///
///
/// Type.
///
public float GetSndPitch(string sndName, string type)
{
if(type == "MUSIC") //check type
{
if(myMusicSounds.TryGetValue(sndName, out audioSourceTemp))
{
return audioSourceTemp.pitch;
}
}
else if(type == "SFX")//check type
{
if (mySFXSounds.TryGetValue(sndName, out audioSourceTemp))
{
return audioSourceTemp.pitch;
}
}
Debug.LogError("Unable to get sndpitch of " + sndName+ " of type " + type);
return 0.0f;
}
#endregion
}