Reading Assets from folders was only possible in Editor over LoadAssetFromPath. Now I'm using asset bundles for ScriptedObjects and Audio Prefabs, when the project is built. When in Editor the folders are still used for convenience (can make changes to assets without rebuilding asset bundles)
218 lines
6.5 KiB
C#
218 lines
6.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using log4net;
|
|
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; }
|
|
}
|
|
|
|
} |