/* * author: mark joshwel * date: 29/5/2024 * description: audio manager for handling audio in the game */ using System; using UnityEngine; /// /// singleton class for handling audio in the game /// public class AudioManager : MonoBehaviour { /// /// enum for available audio channels in the game /// public enum AudioChannel { Music, SoundEffects } /// /// singleton pattern: define instance field for accessing the singleton elsewhere /// public static AudioManager Instance; /// /// music audio source /// [SerializeField] private AudioSource musicSource; /// /// sound effects (sfx) audio source /// [SerializeField] private AudioSource sfxSource; /// /// music source default volume /// [SerializeField] private float musicSourceDefaultVolume = 0.6f; /// /// sound effects (sfx) source default volume /// [SerializeField] private float sfxSourceDefaultVolume = 0.6f; /// /// enforces singleton behaviour; sets doesn't destroy on load and checks for multiple instances /// private void Awake() { // check if instance hasn't been set yet if (Instance == null) { Debug.Log("awake as singleton instance, setting self as the forever-alive instance"); Instance = this; DontDestroyOnLoad(gameObject); } // check if instance is already set and it's not this instance else if (Instance != null && Instance != this) { Debug.Log("awake as non-singleton instance, destroying self"); Destroy(gameObject); } } /// /// function to set default volumes for the audio sources /// public void Start() { // set the default volume for the music source musicSource.volume = musicSourceDefaultVolume; // set the default volume for the sfx source sfxSource.volume = sfxSourceDefaultVolume; } /// /// plays the audio clip once on a given channel /// /// the audio clip to play /// the audio channel to play the clip on public void PlayClipOnChannel(AudioClip clip, AudioChannel channel) { switch (channel) { case AudioChannel.Music: musicSource.PlayOneShot(clip); break; case AudioChannel.SoundEffects: sfxSource.PlayOneShot(clip); break; default: Debug.LogError($"invalid channel '{channel}'"); break; } } /// /// gets the volume of a given audio channel /// /// the AudioManager.AudioChannel to get the volume of /// volume float value of the channel, from 0.0f-1.0f public float GetChannelVolume(AudioChannel channel) { switch (channel) { case AudioChannel.Music: return musicSource.volume; case AudioChannel.SoundEffects: return sfxSource.volume; default: Debug.LogError($"invalid channel '{channel}'"); return 0f; } } /// /// sets the pure volume value of a given audio channel /// /// volume float value for the channel, from 0.0f-1.0f /// the AudioManager.AudioChannel to set the volume of public void SetChannelVolumeReal(float volume, AudioChannel channel) { switch (channel) { case AudioChannel.Music: musicSource.volume = Math.Min(volume, 1.0f); break; case AudioChannel.SoundEffects: sfxSource.volume = Math.Min(volume, 1.0f); break; default: Debug.LogError($"invalid channel '{channel}'"); break; } } /// /// sets the volume value of a given audio channel based on a logarithmic scale /// for human perception (e.g. 0.5f is half volume, 0.1f is very quiet) /// /// volume float value for the channel, from 0.0f-1.0f /// the AudioManager.AudioChannel to set the volume of public void SetChannelVolumeLog(float volume, AudioChannel channel) { switch (channel) { case AudioChannel.Music: musicSource.volume = Mathf.Log10(Mathf.Max(volume, 0.0001f)) * 20; break; case AudioChannel.SoundEffects: sfxSource.volume = Mathf.Log10(Mathf.Max(volume, 0.0001f)) * 20; break; default: Debug.LogError($"invalid channel '{channel}'"); break; } } }