WinterJamSnowman/Assets/Scripts/LemonGenericLib/Audio/AudioManager2D.cs

531 lines
21 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
//plans for the future:
//create a dictionary driven option
//make it compatible with enums
//use pooling audio channels instead when developing version2.0
//namespace Lemon.GenericLib.Audio {
public class AudioManager2D : MonoBehaviour
{
public static AudioManager2D Instance;
//there are 4 seperate audio streams here, make sure they are assigned
[Header("audio sources")]
[SerializeField] private AudioSource soundAudioSrc;
[SerializeField] private AudioSource bgmAudioSource;
[SerializeField] private AudioSource uiAudioSource;
[SerializeField] private AudioSource ambientAudioSource;
[SerializeField] float masterVolume = 1;
[SerializeField] bool changeOtherSources = false;
[SerializeField] bool playOnStart = false;
[SerializeField] string startingAudio = "";
[SerializeField] AudioSource[] extraAudioThreads; //best for sound effects
[Header("extra effects config")]
[SerializeField] float fadeAudioEffectSpeed = 1;
[Header("audio to play")]
[SerializeField] Audio[] audioArray;
//the index for the audio array to track what is playing
//-1 means nothing is playing in that
private int currentSoundIndex = -1;
private int currentBGMIndex = -1;
private int currentUISoundIndex = -1;
private int currentAmbientIndex = -1;
//singleton pattern
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
if (Instance != this)
{
Destroy(gameObject);
}
}
private void Start()
{
if (playOnStart)
{
Play(startingAudio);
}
}
//does not support extra threads
//called when changed volume
public void SetVolume(float vol)
{
this.masterVolume = vol / 100;
UpdateAudioSrcVolume(currentSoundIndex, Audio.AudioType.Sound);
UpdateAudioSrcVolume(currentBGMIndex, Audio.AudioType.BGM);
UpdateAudioSrcVolume(currentUISoundIndex, Audio.AudioType.UISounds);
UpdateAudioSrcVolume(currentAmbientIndex, Audio.AudioType.Ambient);
//this also needs to change audio in audio sources outside
//not the best method
if (!changeOtherSources) return;
var audioSrcList = FindObjectsOfType<AudioSource>();
foreach (var audioSrc in audioSrcList)
{
if (audioSrc != soundAudioSrc && audioSrc != bgmAudioSource && audioSrc != uiAudioSource && audioSrc != ambientAudioSource)
audioSrc.volume = masterVolume;
}
}
//does not support extra threads
private void UpdateAudioSrcVolume(int audioIndex = 0, Audio.AudioType type = Audio.AudioType.BGM)
{
if (audioIndex >= 0)
{
switch (audioArray[audioIndex].audioType)
{
case Audio.AudioType.Sound:
audioArray[audioIndex].updateVolume(soundAudioSrc, this.masterVolume);
break;
case Audio.AudioType.BGM:
audioArray[audioIndex].updateVolume(bgmAudioSource, this.masterVolume);
break;
case Audio.AudioType.UISounds:
audioArray[audioIndex].updateVolume(uiAudioSource, this.masterVolume);
break;
case Audio.AudioType.Ambient:
audioArray[audioIndex].updateVolume(ambientAudioSource, this.masterVolume);
break;
default:
Debug.LogError($"the audio clip {audioArray[audioIndex].audioName} does not have a audio type assigned \n or there is no update volume option for that type yet");
break;
}
}
else
{
switch (type)
{
case Audio.AudioType.Sound:
soundAudioSrc.volume = masterVolume;
break;
case Audio.AudioType.BGM:
bgmAudioSource.volume = masterVolume;
break;
case Audio.AudioType.UISounds:
uiAudioSource.volume = masterVolume;
break;
case Audio.AudioType.Ambient:
ambientAudioSource.volume = masterVolume;
break;
default:
Debug.LogError($"the audio clip {audioArray[audioIndex].audioName} does not have a audio type assigned \n or there is no update volume option for that type yet");
break;
}
}
}
//force all audio to stop
public void StopAllAudio()
{
//this is the solution to manage fading for now
StopCoroutine("FadeAudioEffect");
soundAudioSrc.Stop();
bgmAudioSource.Stop();
uiAudioSource.Stop();
ambientAudioSource.Stop();
foreach (var audioSrc in extraAudioThreads)
{
audioSrc.Stop();
}
}
public void StopSound()
{
soundAudioSrc.Stop();
}
public void StopBGM()
{
bgmAudioSource.Stop();
}
public void StopUISound()
{
uiAudioSource.Stop();
}
public void StopAmbient()
{
ambientAudioSource.Stop();
}
public void StopExtra()
{
foreach (var audioSrc in extraAudioThreads)
{
audioSrc.Stop();
}
}
public void Stop(int audioTypeIndex)
{
if (audioTypeIndex == (int)Audio.AudioType.Sound)
{
soundAudioSrc.Stop();
}
else if (audioTypeIndex == (int)Audio.AudioType.BGM)
{
bgmAudioSource.Stop();
}
else if (audioTypeIndex == (int)Audio.AudioType.UISounds)
{
uiAudioSource.Stop();
}
else if (audioTypeIndex == (int)Audio.AudioType.Ambient)
{
ambientAudioSource.Stop();
}
else
{
Debug.LogError($"the audio index {audioTypeIndex} cis not a valid audio type\nPlease use 1 - 4 ");
}
}
public void SetFadeEffectSpeed(float newEffectSpeed)
{
fadeAudioEffectSpeed = newEffectSpeed;
}
//does not support extra threads
public void PlayFade(string audioName)
{
for (int i = 0; i < audioArray.Length; i++)
{
//Debug.Log(audioName + " " + audioArray[i].audioName);
if (audioArray[i].audioName.ToUpper() == audioName.ToUpper())
{
switch (audioArray[i].audioType)
{
case Audio.AudioType.Sound:
StartCoroutine(FadeAudioEffect(soundAudioSrc, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(soundAudioSrc, masterVolume);
currentSoundIndex = i;
break;
case Audio.AudioType.BGM:
StartCoroutine(FadeAudioEffect(bgmAudioSource, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(bgmAudioSource, masterVolume);
currentBGMIndex = i;
break;
case Audio.AudioType.UISounds:
StartCoroutine(FadeAudioEffect(uiAudioSource, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(uiAudioSource, masterVolume);
currentUISoundIndex = i;
break;
case Audio.AudioType.Ambient:
StartCoroutine(FadeAudioEffect(ambientAudioSource, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(ambientAudioSource, masterVolume);
currentAmbientIndex = i;
break;
default:
Debug.LogError($"the audio clip {audioArray[i].audioName} does not have a audio type assigned \n or there is no play option for that type yet");
break;
}
return;
}
}
Debug.LogError($"the audio clip {audioName} cannot be found\n please check that your spelling is correct");
}
//does not support extra threads
public void PlayFade(string audioName, float fadeAudioEffectSpeed)
{
for (int i = 0; i < audioArray.Length; i++)
{
//Debug.Log(audioName + " " + audioArray[i].audioName);
if (audioArray[i].audioName.ToUpper() == audioName.ToUpper())
{
switch (audioArray[i].audioType)
{
case Audio.AudioType.Sound:
StopCoroutine("FadeAudioEffect");
StartCoroutine(FadeAudioEffect(soundAudioSrc, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(soundAudioSrc, masterVolume);
currentSoundIndex = i;
break;
case Audio.AudioType.BGM:
StopCoroutine("FadeAudioEffect");
StartCoroutine(FadeAudioEffect(bgmAudioSource, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(bgmAudioSource, masterVolume);
currentBGMIndex = i;
break;
case Audio.AudioType.UISounds:
StopCoroutine("FadeAudioEffect");
StartCoroutine(FadeAudioEffect(uiAudioSource, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(uiAudioSource, masterVolume);
currentUISoundIndex = i;
break;
case Audio.AudioType.Ambient:
StopCoroutine("FadeAudioEffect");
StartCoroutine(FadeAudioEffect(ambientAudioSource, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(ambientAudioSource, masterVolume);
currentAmbientIndex = i;
break;
default:
Debug.LogError($"the audio clip {audioArray[i].audioName} does not have a audio type assigned \n or there is no play option for that type yet");
break;
}
return;
}
}
Debug.LogError($"the audio clip {audioName} cannot be found\n please check that your spelling is correct");
}
//does not support extra threads
//0 = sound, 1 is BGM, 2 is UI, 3 is ambient
public void StopFade(int audioTypeIndex)
{
if (audioTypeIndex == (int)Audio.AudioType.Sound)
{
StartCoroutine(FadeAudioEffect(soundAudioSrc, fadeAudioEffectSpeed, soundAudioSrc.volume, false));
}
else if (audioTypeIndex == (int)Audio.AudioType.BGM)
{
StartCoroutine(FadeAudioEffect(bgmAudioSource, fadeAudioEffectSpeed, bgmAudioSource.volume, false));
}
else if (audioTypeIndex == (int)Audio.AudioType.UISounds)
{
StartCoroutine(FadeAudioEffect(uiAudioSource, fadeAudioEffectSpeed, uiAudioSource.volume, false));
}
else if (audioTypeIndex == (int)Audio.AudioType.Ambient)
{
StartCoroutine(FadeAudioEffect(ambientAudioSource, fadeAudioEffectSpeed, ambientAudioSource.volume, false));
}
else
{
Debug.LogError($"the audio index {audioTypeIndex} cis not a valid audio type\nPlease use 1 - 4 ");
}
}
//does not support extra threads
public void StopFade(int audioTypeIndex, float fadeAudioEffectSpeed)
{
if (audioTypeIndex == (int)Audio.AudioType.Sound)
{
StartCoroutine(FadeAudioEffect(soundAudioSrc, fadeAudioEffectSpeed, soundAudioSrc.volume, false));
}
else if (audioTypeIndex == (int)Audio.AudioType.BGM)
{
StartCoroutine(FadeAudioEffect(bgmAudioSource, fadeAudioEffectSpeed, bgmAudioSource.volume, false));
}
else if (audioTypeIndex == (int)Audio.AudioType.UISounds)
{
StartCoroutine(FadeAudioEffect(uiAudioSource, fadeAudioEffectSpeed, uiAudioSource.volume, false));
}
else if (audioTypeIndex == (int)Audio.AudioType.Ambient)
{
StartCoroutine(FadeAudioEffect(ambientAudioSource, fadeAudioEffectSpeed, ambientAudioSource.volume, false));
}
else
{
Debug.LogError($"the audio index {audioTypeIndex} cis not a valid audio type\nPlease use 1 - 4 ");
}
}
IEnumerator FadeAudioEffect(AudioSource audioSource, float effectSpeed, float MaxVolume, bool increment = true)
{
float currentVolume = 0;
if (increment)
{
currentVolume = 0;
while (currentVolume < MaxVolume)
{
audioSource.volume = currentVolume;
currentVolume += Time.deltaTime * 0.01f * effectSpeed;
yield return null;
}
}
else
{
Debug.Log("fading");
currentVolume = MaxVolume;
while (currentVolume > 0)
{
audioSource.volume = currentVolume;
currentVolume -= Time.deltaTime * 0.01f * effectSpeed;
yield return null;
}
}
}
//use audio name to play audio, I know it is a string but what choice we have, maybe change to scriptable object when we have time
public void Play(string audioName)
{
for (int i = 0; i < audioArray.Length; i++)
{
//Debug.Log(audioName + " " + audioArray[i].audioName);
if (audioArray[i].audioName.ToUpper() == audioName.ToUpper())
{
switch (audioArray[i].audioType)
{
case Audio.AudioType.Sound:
StopCoroutine("FadeAudioEffect");
audioArray[i].Play(soundAudioSrc, masterVolume);
currentSoundIndex = i;
break;
case Audio.AudioType.BGM:
StopCoroutine("FadeAudioEffect");
audioArray[i].Play(bgmAudioSource, masterVolume);
currentBGMIndex = i;
break;
case Audio.AudioType.UISounds:
StopCoroutine("FadeAudioEffect");
audioArray[i].Play(uiAudioSource, masterVolume);
currentUISoundIndex = i;
break;
case Audio.AudioType.Ambient:
StopCoroutine("FadeAudioEffect");
audioArray[i].Play(ambientAudioSource, masterVolume);
currentAmbientIndex = i;
break;
case Audio.AudioType.Extra:
if (audioArray[i].extraThreadIndex < 0 || audioArray[i].extraThreadIndex >= extraAudioThreads.Length)
{
Debug.LogError($"the audio clip {audioArray[i].audioName} has a invalid extra audio thread index of {audioArray[i].extraThreadIndex}");
}
else
{
StopCoroutine("FadeAudioEffect");
audioArray[i].Play(extraAudioThreads[audioArray[i].extraThreadIndex], masterVolume);
}
break;
default:
Debug.LogError($"the audio clip {audioArray[i].audioName} does not have a audio type assigned \n or there is no play option for that type yet");
break;
}
return;
}
}
}
public void Play(int index)
{
if (index < 0 || index > audioArray.Length) {
Debug.LogError($"Error: Invalid Audio Index of {index}");
return;
}
switch (audioArray[index].audioType)
{
case Audio.AudioType.Sound:
StopCoroutine("FadeAudioEffect");
audioArray[index].Play(soundAudioSrc, masterVolume);
currentSoundIndex = index;
break;
case Audio.AudioType.BGM:
StopCoroutine("FadeAudioEffect");
audioArray[index].Play(bgmAudioSource, masterVolume);
currentBGMIndex = index;
break;
case Audio.AudioType.UISounds:
StopCoroutine("FadeAudioEffect");
audioArray[index].Play(uiAudioSource, masterVolume);
currentUISoundIndex = index;
break;
case Audio.AudioType.Ambient:
StopCoroutine("FadeAudioEffect");
audioArray[index].Play(ambientAudioSource, masterVolume);
currentAmbientIndex = index;
break;
case Audio.AudioType.Extra:
if (audioArray[index].extraThreadIndex < 0 || audioArray[index].extraThreadIndex >= extraAudioThreads.Length)
{
Debug.LogError($"the audio clip {audioArray[index].audioName} has a invalid extra audio thread index of {audioArray[index].extraThreadIndex}");
}
else
{
StopCoroutine("FadeAudioEffect");
audioArray[index].Play(extraAudioThreads[audioArray[index].extraThreadIndex], masterVolume);
}
break;
default:
Debug.LogError($"the audio clip {audioArray[index].audioName} does not have a audio type assigned \n or there is no play option for that type yet");
break;
}
}
}
//store audio data
[Serializable]
public class Audio
{
public string audioName = "";
public enum AudioType { Sound, BGM, UISounds, Ambient, Extra }
public int extraThreadIndex;
public AudioType audioType = AudioType.Sound;
public AudioClip clip;
public bool loop = false;
public float defaultVolume = 1;
public void Play(AudioSource audioSrc, float volume)
{
audioSrc.clip = clip;
audioSrc.volume = defaultVolume * volume;
audioSrc.loop = loop;
audioSrc.Play();
}
public void updateVolume(AudioSource audioSrc, float volume)
{
Debug.Log("update");
audioSrc.volume = defaultVolume * volume;
}
}
//}