unified audio manager that limits the number of simultaneous sounds in certain categories

This commit is contained in:
Ian Woods 2026-06-30 20:12:03 -07:00
parent d53a2a47e2
commit 404c749a43
9 changed files with 154 additions and 110 deletions

View file

@ -0,0 +1,74 @@
// Assets/_Project/Scripts/Audio/AudioManager.cs
using System.Collections.Generic;
using UnityEngine;
namespace TD.Audio
{
public class AudioManager : MonoBehaviour
{
[System.Serializable]
public struct CategoryConfig
{
public AudioCategory category;
public int maxVoices;
[Range(0f, 1f)]
public float volume;
}
public static AudioManager Instance { get; private set; }
[SerializeField] private CategoryConfig[] categories;
private Dictionary<AudioCategory, AudioSource[]> pools;
private Dictionary<AudioCategory, int> indices;
private void Awake()
{
if (Instance != null)
{
Destroy(gameObject);
return;
}
Instance = this;
InitializePools();
}
private void OnDestroy()
{
if (Instance == this) Instance = null;
}
private void InitializePools()
{
pools = new Dictionary<AudioCategory, AudioSource[]>();
indices = new Dictionary<AudioCategory, int>();
foreach (var config in categories)
{
var pool = new AudioSource[config.maxVoices];
for (int i = 0; i < config.maxVoices; i++)
{
var src = gameObject.AddComponent<AudioSource>();
src.playOnAwake = false;
src.volume = config.volume;
pool[i] = src;
}
pools[config.category] = pool;
indices[config.category] = 0;
}
}
public void Play(AudioClip clip, AudioCategory category, float pitch = 1f)
{
if (clip == null) return;
if (!pools.TryGetValue(category, out var pool)) return;
int idx = indices[category];
var src = pool[idx % pool.Length];
src.pitch = pitch;
src.clip = clip;
src.Play();
indices[category] = idx + 1;
}
}
}