220 lines
6.5 KiB
C#
220 lines
6.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using log4net;
|
|
using UnityEditor;
|
|
using UnityEditor.PackageManager;
|
|
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<ManageableAudio, GameObject> audioDictionary =
|
|
new Dictionary<ManageableAudio, GameObject>();
|
|
|
|
public delegate void OnAudioEffectBroadcast(AudioEffectBroadCastEventArgs args);
|
|
public event OnAudioEffectBroadcast AudioEffectBroadcasted;
|
|
|
|
// 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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Instantiates a sound from the library which will be used for global and
|
|
/// scene independent sound.
|
|
/// </summary>
|
|
/// <param name="prefabName">Name of the sound prefab</param>
|
|
/// <param name="dependsOnScene">Should the audio be destroyed, when the calling scene is destroyed?</param>
|
|
/// <returns>ManageableAudio instance to control the playback with.</returns>
|
|
public ManageableAudio GetGlobalSoundByName(string prefabName, bool dependsOnScene = false)
|
|
{
|
|
return GetGlobalSound(null, -1, dependsOnScene, SearchSound(null, -1, prefabName));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <param name="prefabName">Name of the sound prefab</param>
|
|
/// <param name="transform">Transform which will parent the sound object.</param>
|
|
/// <returns>ManageableAudio instance to control the playback with.</returns>
|
|
public ManageableAudio GetLocalSoundByName(string prefabName, Transform transform)
|
|
{
|
|
return GetLocalSound(null, -1, transform, SearchSound(null, -1, prefabName));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Instantiates a sound from the library which will be used for global sound.
|
|
/// The ManageableAudio object is instantiated in the currently active scene,
|
|
/// when dependsOnScene is true!
|
|
/// </summary>
|
|
/// <param name="audioTag">Tag of the sound</param>
|
|
/// <param name="id">ID of the sound</param>
|
|
/// <param name="dependsOnScene">Should the audio be destroyed, when the calling scene is destroyed?</param>
|
|
/// <param name="go">Optionally provide the sound GameObject directly.</param>
|
|
/// <returns>ManageableAudio instance to control the playback with.</returns>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <param name="audioTag">Tag of the sound</param>
|
|
/// <param name="id">ID of the sound</param>
|
|
/// <param name="newParent">Transform which will parent the sound object.</param>
|
|
/// <param name="go"> Optionally provide the sound GameObject directly.</param>
|
|
/// <returns>ManageableAudio instance to control the playback with.</returns>
|
|
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<ManageableAudio, GameObject> ReadLibrary(AudioLibrary al)
|
|
{
|
|
Dictionary<ManageableAudio, GameObject> audioDictionary =
|
|
new Dictionary<ManageableAudio, GameObject>();
|
|
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)
|
|
{
|
|
try
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Error(e.Message);
|
|
return null;
|
|
}
|
|
|
|
}
|
|
|
|
public void BroadcastAudioEffect(AudioEffects effect, Transform t, bool activate)
|
|
{
|
|
AudioEffectBroadcasted.Invoke(new AudioEffectBroadCastEventArgs
|
|
{
|
|
AffectedParent = t,
|
|
Effect = effect,
|
|
Activate = activate
|
|
});
|
|
}
|
|
|
|
}
|
|
public class AudioEffectBroadCastEventArgs : EventArgs
|
|
{
|
|
public Transform AffectedParent { get; set; }
|
|
public AudioEffects Effect { get; set; }
|
|
public bool Activate { get; set; }
|
|
}
|
|
|
|
} |