207 lines
7.1 KiB
C#
207 lines
7.1 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
namespace BulletHellTemplate
|
|
{
|
|
/// <summary>
|
|
/// Serializable structure to hold custom audio tag and its volume.
|
|
/// </summary>
|
|
[System.Serializable]
|
|
public struct CustomAudioTag
|
|
{
|
|
public string tag;
|
|
[Range(0, 1)]
|
|
public float volume;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singleton class that manages audio volumes and plays audio clips globally with performance optimizations.
|
|
/// </summary>
|
|
public class AudioManager : MonoBehaviour
|
|
{
|
|
[Header("Audio Source")]
|
|
[Tooltip("The main audio source for Master volume.")]
|
|
public AudioSource masterAudioSource;
|
|
|
|
[Header("Volume Settings")]
|
|
[Tooltip("Global volume for all sounds.")]
|
|
[Range(0, 1)]
|
|
public float masterVolume = 1.0f;
|
|
|
|
[Tooltip("Volume for VFX sounds.")]
|
|
[Range(0, 1)]
|
|
public float vfxVolume = 1.0f;
|
|
|
|
[Tooltip("Volume for ambient sounds.")]
|
|
[Range(0, 1)]
|
|
public float ambienceVolume = 1.0f;
|
|
|
|
[Tooltip("Custom tag volumes, developers can add their own audio tags.")]
|
|
public List<CustomAudioTag> customTagVolumes = new List<CustomAudioTag>();
|
|
|
|
[Header("Audio Limitations")]
|
|
[Tooltip("The maximum number of audios that can be played at the same time. 0 = unlimited")]
|
|
public int maxConcurrentAudio = 10;
|
|
|
|
private int currentAudioCount = 0;
|
|
public AudioSource ambientAudioSource; // Separate source for ambient sounds
|
|
public AudioSource loadingAudioSource;
|
|
public static AudioManager Singleton;
|
|
|
|
private void Awake()
|
|
{
|
|
if (Singleton == null)
|
|
{
|
|
Singleton = this;
|
|
DontDestroyOnLoad(gameObject);
|
|
ambientAudioSource.loop = true; // Loop for ambient sounds
|
|
}
|
|
else
|
|
{
|
|
Destroy(gameObject);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Plays an ambient audio clip in a loop with the specified tag.
|
|
/// Does not affect the current audio count or maxConcurrentAudio.
|
|
/// </summary>
|
|
/// <param name="clip">The audio clip to play.</param>
|
|
/// <param name="tag">The tag used to determine the volume.</param>
|
|
public void PlayAmbientAudio(AudioClip clip, string tag)
|
|
{
|
|
// Stop the loading audio if it's playing
|
|
if (loadingAudioSource.isPlaying)
|
|
{
|
|
loadingAudioSource.Stop();
|
|
}
|
|
if (ambientAudioSource.isPlaying)
|
|
{
|
|
ambientAudioSource.Stop();
|
|
}
|
|
|
|
// Play ambient audio
|
|
float volume = GetVolumeByTag(tag);
|
|
ambientAudioSource.volume = volume;
|
|
ambientAudioSource.clip = clip;
|
|
ambientAudioSource.loop = true; // Ensure the ambient audio is set to loop
|
|
ambientAudioSource.Play();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Plays a loading menu audio clip and stops the ambient audio.
|
|
/// The ambient audio will be stopped and prevented from playing again until reloaded.
|
|
/// </summary>
|
|
/// <param name="clip">The audio clip to play.</param>
|
|
/// <param name="tag">The tag used to determine the volume.</param>
|
|
public void PlayLoadingMenu(AudioClip clip, string tag)
|
|
{
|
|
// Stop the ambient audio to prevent it from playing during the loading menu
|
|
if (ambientAudioSource.isPlaying)
|
|
{
|
|
ambientAudioSource.Stop();
|
|
ambientAudioSource.clip = null; // Prevent ambient audio from automatically replaying
|
|
}
|
|
|
|
// Play the loading menu audio
|
|
float volume = GetVolumeByTag(tag);
|
|
loadingAudioSource.volume = volume;
|
|
loadingAudioSource.PlayOneShot(clip); // PlayOneShot doesn't require setting the clip to null
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stops all currently playing audio, including ambient and loading audio.
|
|
/// This function is useful when the game ends or the player dies,
|
|
/// ensuring that no audio is left playing.
|
|
/// </summary>
|
|
public void StopAllAudioPlay()
|
|
{
|
|
// Stop the master audio source if it's playing
|
|
if (masterAudioSource.isPlaying)
|
|
{
|
|
masterAudioSource.Stop();
|
|
}
|
|
|
|
// Stop the ambient audio source if it's playing
|
|
if (ambientAudioSource.isPlaying)
|
|
{
|
|
ambientAudioSource.Stop();
|
|
}
|
|
|
|
// Stop the loading audio source if it's playing
|
|
if (loadingAudioSource.isPlaying)
|
|
{
|
|
loadingAudioSource.Stop();
|
|
}
|
|
|
|
// Reset the current audio count
|
|
currentAudioCount = 0;
|
|
}
|
|
public void StopLoadingAudioPlay()
|
|
{
|
|
// Stop the loading audio source if it's playing
|
|
if (loadingAudioSource.isPlaying)
|
|
{
|
|
loadingAudioSource.Stop();
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Plays an audio clip using PlayOneShot with the specified tag.
|
|
/// Limits the number of concurrently playing audio clips and adjusts the volume based on the tag.
|
|
/// </summary>
|
|
public void PlayAudio(AudioClip clip, string tag)
|
|
{
|
|
if (maxConcurrentAudio > 0 && currentAudioCount >= maxConcurrentAudio)
|
|
{
|
|
Debug.Log("Audio limit reached. Skipping this sound.");
|
|
return;
|
|
}
|
|
|
|
// Determine the volume based on the tag
|
|
float volume = GetVolumeByTag(tag);
|
|
masterAudioSource.volume = volume;
|
|
masterAudioSource.PlayOneShot(clip);
|
|
|
|
currentAudioCount++;
|
|
|
|
// Automatically reduce the count after the audio finishes
|
|
StartCoroutine(ReduceAudioCountAfterPlaying(clip.length));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the volume based on the tag.
|
|
/// </summary>
|
|
private float GetVolumeByTag(string tag)
|
|
{
|
|
switch (tag.ToLower())
|
|
{
|
|
case "master":
|
|
return masterVolume;
|
|
case "vfx":
|
|
return vfxVolume;
|
|
case "ambient":
|
|
return ambienceVolume;
|
|
default:
|
|
foreach (var customTag in customTagVolumes)
|
|
{
|
|
if (customTag.tag == tag)
|
|
{
|
|
return customTag.volume;
|
|
}
|
|
}
|
|
Debug.LogWarning($"Audio tag '{tag}' not recognized. Using Master volume as default.");
|
|
return masterVolume;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reduces the audio count after a certain amount of time (the clip length).
|
|
/// </summary>
|
|
private IEnumerator<WaitForSeconds> ReduceAudioCountAfterPlaying(float clipLength)
|
|
{
|
|
yield return new WaitForSeconds(clipLength);
|
|
currentAudioCount--;
|
|
}
|
|
}
|
|
}
|