feature: Created audio manager

This commit is contained in:
Gerard Gascón 2024-01-28 10:00:46 +01:00
parent cb907bc76a
commit 2f9b516605
10 changed files with 778 additions and 22 deletions

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1f323de77930b4a45a85c388886626ee
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,294 @@
using System;
using System.Collections;
using UnityEngine;
namespace Audio {
public class AudioManager : MonoBehaviour {
public static AudioManager instance;
[SerializeField] private Sounds soundList;
private void Awake() {
if (instance == null) {
instance = this;
} else {
Destroy(gameObject);
return;
}
DontDestroyOnLoad(gameObject);
foreach (Sounds.List s in soundList.sounds) {
if (string.IsNullOrEmpty(s.name) || string.IsNullOrWhiteSpace(s.name)) {
Debug.LogWarning("The name one sound is empty");
continue;
}
GameObject sound = new(s.name) {
transform = {
parent = transform
}
};
s.source = sound.AddComponent<AudioSource>();
if (soundList.mainMixer && soundList.sfxMixer) {
s.source.outputAudioMixerGroup = s.type == Sounds.List.Type.Music ? soundList.mainMixer : soundList.sfxMixer;
}
s.source.clip = s.clip;
s.source.volume = s.volume;
s.source.pitch = s.pitch;
s.source.loop = s.loop;
}
}
#region Play
/// <summary>Use this to play a sound with a specific name
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="name" type="string">The name of the sound</param>
public void Play(string name) {
Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name);
if (s == null) {
Debug.LogWarning("Sound: " + name + " not found!");
return;
}
s.source.pitch = s.RandomPitch;
s.source.volume = s.RandomVolume;
s.source.Play();
}
/// <summary>Use this to play a sound with a specific name and with a certain delay
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="name" type="string">The name of the sound</param>
/// <param name="delay" type="float">The delay in seconds</param>
public void Play(string name, float delay) {
Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name);
if (s == null) {
Debug.LogWarning("Sound: " + name + " not found!");
return;
}
s.source.pitch = s.RandomPitch;
s.source.volume = s.RandomVolume;
s.source.PlayDelayed(delay);
}
/// <summary>Use this to play one shot of a sound with a specific name
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="name" type="string">The name of the sound</param>
public void PlayOneShot(string name) {
Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name);
if (s == null) {
Debug.LogWarning("Sound: " + name + " not found!");
return;
}
s.source.pitch = s.RandomPitch;
s.source.volume = s.RandomVolume;
s.source.PlayOneShot(s.clip);
}
/// <summary>Use this to play an intro song and then start playing the song loop
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="intro" type="string">The name of the intro song</param>
/// <param name="song" type="string">The name of the song loop</param>
public void PlayWithIntro(string intro, string song) {
Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == intro);
if (s == null) {
Debug.LogWarning("Sound: " + intro + " not found!");
return;
}
s.source.pitch = s.RandomPitch;
s.source.volume = s.RandomVolume;
s.source.Play();
float introDuration = s.clip.length;
Play(song, introDuration);
}
/// <summary>Use this to play one shot of a random sound within a list
/// <para>They have to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="names" type="string[]">The names of the sounds</param>
public void PlayRandomSound(params string[] names) {
int random = UnityEngine.Random.Range(0, names.Length);
PlayOneShot(names[random]);
}
#endregion
#region Pause
/// <summary>Use this to pause a sound with a specific name
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="name" type="string">The name of the sound</param>
public void Pause(string name) {
Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name);
if (s == null) {
Debug.LogWarning("Sound: " + name + " not found!");
return;
}
s.source.pitch = s.RandomPitch;
s.source.volume = s.RandomVolume;
s.source.Pause();
}
/// <summary>Use this to unpause a sound with a specific name
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="name" type="string">The name of the sound</param>
public void UnPause(string name) {
Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name);
if (s == null) {
Debug.LogWarning("Sound: " + name + " not found!");
return;
}
s.source.pitch = s.RandomPitch;
s.source.volume = s.RandomVolume;
s.source.UnPause();
}
#endregion
#region Stop
/// <summary>Use this to stop a sound with a specific name
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="name" type="string">The name of the sound</param>
public void Stop(string name) {
Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name);
if (s == null) {
Debug.LogWarning("Sound: " + name + " not found!");
return;
}
s.source.pitch = s.RandomPitch;
s.source.volume = s.RandomVolume;
s.source.Stop();
}
/// <summary>Use this to stop all the sounds
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
public void StopAll() {
foreach (Sounds.List s in soundList.sounds) {
if (s.source) {
s.source.Stop();
}
}
}
#endregion
/// <summary>This function returns the AudioSource that contains a specific sound
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="name">The name of the sound</param>
/// <returns>The AudioSource in the scene</returns>
public AudioSource GetSource(string name) {
Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name);
if (s == null) {
Debug.LogWarning("Sound: " + name + " not found!");
return null;
}
return s.source;
}
#region Fades
/// <summary>Use this to start playing a sound with a fade in
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="name" type="string">The name of the sound</param>
/// <param name="duration" type="float">The duration of the fade in</param>
public void FadeIn(string name, float duration) {
StartCoroutine(FadeInCoroutine(name, duration));
}
IEnumerator FadeInCoroutine(string name, float fadeTime) {
AudioSource audioSource = GetSource(name);
if (audioSource != null && !audioSource.isPlaying) {
float volume = audioSource.volume;
audioSource.volume = 0;
audioSource.Play();
while (audioSource.volume < volume) {
audioSource.volume += Time.deltaTime / fadeTime;
yield return null;
}
audioSource.volume = volume;
}
}
/// <summary>Use this to stop playing a sound with a fade out
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="name" type="string">The name of the sound</param>
/// <param name="duration" type="float">The duration of the fade out</param>
public void FadeOut(string name, float duration) {
StartCoroutine(FadeOutCoroutine(name, duration));
}
private IEnumerator FadeOutCoroutine(string name, float fadeTime) {
AudioSource audioSource = GetSource(name);
if (!audioSource || !audioSource.isPlaying) yield break;
float startVolume = audioSource.volume;
while (audioSource.volume > 0) {
audioSource.volume -= startVolume * Time.deltaTime / fadeTime;
yield return null;
}
audioSource.Stop();
audioSource.volume = startVolume;
}
/// <summary>Use this to start playing a sound muted
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="name" type="string">The name of the sound</param>
public void PlayMuted(string name) {
Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name);
if (s == null) {
Debug.LogWarning("Sound: " + name + " not found!");
return;
}
s.source.pitch = s.RandomPitch;
s.source.volume = 0f;
s.source.Play();
}
/// <summary>Use this to fade in a sound that is currently muted
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// <para>WARNING: If the PlayMuted hasn't been called before, this function won't work</para>
/// </summary>
/// <param name="name" type="string">The name of the sound</param>
/// <param name="duration">The duration of the fade in</param>
public void FadeMutedIn(string name, float duration) {
StartCoroutine(FadeMutedInCoroutine(name, duration));
}
private IEnumerator FadeMutedInCoroutine(string name, float fadeTime) {
Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name);
if (s == null) {
Debug.LogWarning("Sound: " + name + " not found!");
yield break;
}
while (s.source.volume < s.volume) {
s.source.volume += Time.deltaTime / fadeTime;
yield return null;
}
s.source.volume = s.volume;
}
/// <summary>Use this to fade out a sound and keep playing that muted
/// <para>It has to be in the Sound asset referenced in the AudioManager instance</para>
/// </summary>
/// <param name="name" type="string">The name of the sound</param>
/// <param name="duration">The duration of the fade out</param>
public void FadeMutedOut(string name, float duration) {
StartCoroutine(FadeMutedOutCoroutine(name, duration));
}
private IEnumerator FadeMutedOutCoroutine(string name, float fadeTime) {
Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name);
if (s == null) {
Debug.LogWarning("Sound: " + name + " not found!");
yield break;
}
while (s.source.volume > 0) {
s.source.volume -= Time.deltaTime / fadeTime;
yield return null;
}
s.source.volume = 0;
}
#endregion
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b824c4cae81b29e41acd7881949b2789
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,53 @@
using UnityEngine;
using UnityEngine.Audio;
namespace Audio {
[CreateAssetMenu(fileName = "Sounds", menuName = "Simple Tools/Sounds", order = 11)]
public class Sounds : ScriptableObject {
[Tooltip("The music mixer.")]
public AudioMixerGroup mainMixer;
[Tooltip("The SFX mixer.")]
public AudioMixerGroup sfxMixer;
public List[] sounds;
[System.Serializable]
public class List {
[Tooltip("Name of the sound. Each name has to be different between each other.")]
public string name;
public AudioClip clip;
[System.Serializable] public enum Type { Music, SFX }
[Space]
[Tooltip("Is it part of the music or the SFX?")] public Type type;
[Space]
[Tooltip("Default volume of the sound."), Range(0f, 1f)] public float volume;
[Tooltip("Variance percentage of the volume"), Range(0f, 1f)] public float volumeVariance;
[Tooltip("Default pitch of the sound."), Range(.1f, 3f)] public float pitch;
[Tooltip("Variance percentage of the pitch"), Range(0f, 1f)] public float pitchVariance;
public bool loop;
[HideInInspector] public AudioSource source;
private float _randomVolume;
public float RandomVolume {
get {
_randomVolume = volume * (1f + Random.Range(-volumeVariance / 2f, volumeVariance / 2f));
return _randomVolume;
}
}
private float _randomPitch;
public float RandomPitch {
get {
_randomPitch = pitch * (1f + Random.Range(-pitchVariance / 2f, pitchVariance / 2f));
return _randomPitch;
}
}
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c4ed92ae62204888802bcdb9f4ea768c
timeCreated: 1706432143

View file

@ -23,7 +23,7 @@ namespace Messaging {
answerContainer.InitializeTypers();
}
public void SetMessageText(string text, bool animate, bool isAnswer) {
public Coroutine SetMessageText(string text, bool animate, bool isAnswer) {
Text = text;
IsAnswer = isAnswer;
IsReal = false;
@ -32,17 +32,19 @@ namespace Messaging {
SetText(ref answerContainer.TypingCoroutine, answerContainer.messageText, answerContainer.TextTyper,
text, animate);
if(string.IsNullOrEmpty(text)) return;
if(string.IsNullOrEmpty(text)) return null;
answerContainer.container.SetActive(true);
questionContainer.container.SetActive(false);
} else {
SetText(ref questionContainer.TypingCoroutine, questionContainer.messageText,
questionContainer.TextTyper, text, animate);
if(string.IsNullOrEmpty(text)) return;
questionContainer.container.SetActive(true);
answerContainer.container.SetActive(false);
return answerContainer.TypingCoroutine;
}
SetText(ref questionContainer.TypingCoroutine, questionContainer.messageText,
questionContainer.TextTyper, text, animate);
if(string.IsNullOrEmpty(text)) return null;
questionContainer.container.SetActive(true);
answerContainer.container.SetActive(false);
return questionContainer.TypingCoroutine;
}
public Coroutine SetMessageRealText(string text, bool animate, bool isAnswer) {

View file

@ -56,11 +56,12 @@ namespace Messaging {
}
public void CreateMessage(string message, bool isAnswer) {
ModifyMessageText(message, _messages.Length - 1, isAnswer);
ModifyMessageText(message, _messages.Length - 1, isAnswer, true);
if (isAnswer) {
_currentJokeIndex--;
_currentJokeIndex = Mathf.Max(_currentJokeIndex, 0);
if (message == _currentJoke.AnswerMessage.Key) {
_sendButton.Lock();
StartCoroutine(ShowRealTexts());
if(_currentJokeIndex == 0)
SendRandomJoke(sendJokeLongDelay);
@ -69,6 +70,7 @@ namespace Messaging {
} else {
_lives.Wrong();
if (_lives.CurrentLives == 0) {
_sendButton.Lock();
StartCoroutine(ShowRealTexts());
SendRandomJoke(sendJokeLongDelay);
_lives.ResetLives();
@ -81,6 +83,7 @@ namespace Messaging {
private IEnumerator ShowRealTexts() {
yield return ModifyRealMessageText(_currentJoke.QuestionMessage.Value, _currentJokeIndex, false);
yield return ModifyMessageText(_currentJoke.AnswerMessage.Key, _messages.Length - 1, true, false);
yield return ModifyRealMessageText(_currentJoke.AnswerMessage.Value, _messages.Length - 1, true);
}
@ -111,9 +114,11 @@ namespace Messaging {
return emojiStrings;
}
private void ModifyMessageText(string message, int index, bool isAnswer) {
ModifyPreviousMessage(index);
_messages[index].SetMessageText(message, true, isAnswer);
private Coroutine ModifyMessageText(string message, int index, bool isAnswer, bool createNew) {
if(createNew)
ModifyPreviousMessage(index);
return _messages[index].SetMessageText(message, true, isAnswer);
}
private Coroutine ModifyRealMessageText(string message, int index, bool isAnswer) {