using System.Collections.Generic; using System.Linq; using System.Reflection; using log4net; using UnityEditor; using UnityEngine; namespace Managers { public class AudioManager : MonoBehaviour { private static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public static AudioManager G { get; private set; } [HideInInspector] public AudioLibrary audioLibrary; private Dictionary audioDictionary = new Dictionary(); // Start is called before the first frame update void Awake() { G = this; Log.Info("Awake"); if (gameObject.TryGetComponent(out AudioLibrary al)) { audioLibrary = al; } else { Log.Warn("There is no audio library component in the AudioManager. There will be no sound."); } } void Start() { if (audioLibrary == null) { return; } audioDictionary = ReadLibrary(audioLibrary); } /// /// Instantiates a sound from the library which will be used for global and /// scene independent sound. /// /// Name of the sound prefab /// Should the audio be destroyed, when the calling scene is destroyed? /// ManageableAudio instance to control the playback with. public ManageableAudio GetGlobalSoundByName(string prefabName, bool dependsOnScene = false) { return GetGlobalSound(null, -1, false, SearchSound(null, -1, prefabName)); } /// /// Instantiates a sound from the library which will be used for local, spatial and /// scene dependent sound. It reparents the object(AudioSource + ManageableAudio component), /// to the provided transform. /// /// Name of the sound prefab /// Transform which will parent the sound object. /// ManageableAudio instance to control the playback with. public ManageableAudio GetLocalSoundByName(string prefabName, Transform transform) { return GetLocalSound(null, -1, transform, SearchSound(null, -1, prefabName)); } /// /// Instantiates a sound from the library which will be used for global sound. /// TODO: Only makes sense, if requested prefab has 0 spatial value. /// /// Tag of the sound /// ID of the sound /// Should the audio be destroyed, when the calling scene is destroyed? /// Optionally provide the sound GameObject directly. /// ManageableAudio instance to control the playback with. public ManageableAudio GetGlobalSound(string audioTag, int id, bool dependsOnScene = false, GameObject go = null) { GameObject sound; if (go == null) { sound = SearchSound(audioTag, id); } else { sound = go; } if (sound == null) { Log.Warn($"Requested sound: {audioTag}_{id} was not in the audio library."); return null; } sound = Instantiate(sound); if (!dependsOnScene) sound.transform.SetParent(gameObject.transform); if (sound.TryGetComponent(out ManageableAudio ma)) { return ma; } else { Log.Warn($"Prefab for sound: {audioTag}_{id} contained no ManageableAudio component"); return null; } } /// /// Instantiates a sound from the library which will be used for local, spatial and /// scene dependent sound. It reparents the object(AudioSource + ManageableAudio component), /// to the provided transform. /// /// Tag of the sound /// ID of the sound /// Transform which will parent the sound object. /// Optionally provide the sound GameObject directly. /// ManageableAudio instance to control the playback with. public ManageableAudio GetLocalSound(string audioTag, int id, Transform newParent, GameObject go = null) { GameObject sound; if (go == null) { sound = SearchSound(audioTag, id); } else { sound = go; } if (sound == null) { Log.Warn($"Requested sound: {audioTag}_{id} was not in the audio library."); return null; } sound = Instantiate(sound); sound.transform.SetParent(newParent, false); if (sound.TryGetComponent(out ManageableAudio ma)) { return ma; } else { Log.Warn($"Prefab for sound: {audioTag}_{id} contained no ManageableAudio component"); return null; } } // There are sounds which are scene independent and always global -> will continue playing even if the scene invoking is destroyed // -"- scene dependent and global -> will play globally but when the scene is destroyed they will be also destroyed // -"- scene dependent and local -> will play spatially from a object and be destroyed when the scene is destroyed // Dictionary ReadLibrary(AudioLibrary al) { Dictionary audioDictionary = new Dictionary(); foreach (GameObject go in al.audios) { if (go.TryGetComponent(out ManageableAudio ma)) { audioDictionary.Add(ma, go); } } return audioDictionary; } private GameObject SearchSound(string audioTag = null, int id = -1, string prefabName = null) { if (prefabName == null) { return audioDictionary. Where(manageableAudio => manageableAudio.Key.audioTag == audioTag). First(manageableAudio => manageableAudio.Key.id == id).Value; } else { return audioDictionary. First(manageableAudio => manageableAudio.Value.name == prefabName).Value; } } } }