104 lines
3.3 KiB
C#
104 lines
3.3 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Audio;
|
|
|
|
namespace Hallucinate.Audio
|
|
{
|
|
public class AudioManager : MonoBehaviour
|
|
{
|
|
public static AudioManager Instance { get; private set; }
|
|
|
|
[Header("Settings")]
|
|
[SerializeField] private AudioDatabase database;
|
|
[SerializeField] private int poolSize = 20;
|
|
[SerializeField] private AudioMixerGroup defaultGroup;
|
|
|
|
private List<AudioSource> _pool;
|
|
private int _currentIndex = 0;
|
|
|
|
private void Awake()
|
|
{
|
|
if (Instance != null && Instance != this)
|
|
{
|
|
Destroy(gameObject);
|
|
return;
|
|
}
|
|
Instance = this;
|
|
DontDestroyOnLoad(gameObject);
|
|
|
|
InitializePool();
|
|
if (database != null) database.Initialize();
|
|
}
|
|
|
|
private void InitializePool()
|
|
{
|
|
_pool = new List<AudioSource>();
|
|
for (int i = 0; i < poolSize; i++)
|
|
{
|
|
GameObject go = new GameObject($"AudioSource_{i}");
|
|
go.transform.SetParent(transform);
|
|
AudioSource source = go.AddComponent<AudioSource>();
|
|
source.playOnAwake = false;
|
|
_pool.Add(source);
|
|
}
|
|
}
|
|
|
|
public void Play(string sampleName, float volumeMult = 1f, float pitchMult = 1f, Vector3? position = null)
|
|
{
|
|
if (database == null) return;
|
|
|
|
var sample = database.GetSample(sampleName);
|
|
if (sample == null || sample.Clip == null)
|
|
{
|
|
// Silence or log warning if needed
|
|
return;
|
|
}
|
|
|
|
AudioSource source = GetNextSource();
|
|
|
|
// Setup source
|
|
source.clip = sample.Clip;
|
|
source.volume = sample.DefaultVolume * volumeMult;
|
|
source.pitch = sample.DefaultPitch * pitchMult;
|
|
source.outputAudioMixerGroup = sample.MixerGroup != null ? sample.MixerGroup : defaultGroup;
|
|
|
|
if (position.HasValue)
|
|
{
|
|
source.spatialBlend = 1f; // 3D
|
|
source.transform.position = position.Value;
|
|
}
|
|
else
|
|
{
|
|
source.spatialBlend = 0f; // 2D
|
|
}
|
|
|
|
source.Play();
|
|
}
|
|
|
|
private AudioSource GetNextSource()
|
|
{
|
|
// Simple round-robin for now, can be improved to find truly "idle" sources
|
|
AudioSource source = _pool[_currentIndex];
|
|
_currentIndex = (_currentIndex + 1) % poolSize;
|
|
return source;
|
|
}
|
|
|
|
public void PlayRandom(string baseName, int variants, float volumeMult = 1f, float pitchMult = 1f)
|
|
{
|
|
int rand = UnityEngine.Random.Range(1, variants + 1);
|
|
Play($"{baseName}-{rand}", volumeMult, pitchMult);
|
|
}
|
|
|
|
// Helper for UI/Global easy access
|
|
public static void PlayGlobal(string name, float volume = 1f, float pitch = 1f)
|
|
{
|
|
if (Instance != null) Instance.Play(name, volume, pitch);
|
|
}
|
|
|
|
public static void PlayRandomGlobal(string baseName, int variants, float volume = 1f, float pitch = 1f)
|
|
{
|
|
if (Instance != null) Instance.PlayRandom(baseName, variants, volume, pitch);
|
|
}
|
|
}
|
|
}
|