update
This commit is contained in:
@@ -1,175 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Audio;
|
||||
|
||||
namespace Hallucinate.Audio
|
||||
{
|
||||
public class AudioManager : MonoBehaviour
|
||||
{
|
||||
public static AudioManager Instance { get; private set; }
|
||||
|
||||
[BoxGroup("Settings")]
|
||||
[Required]
|
||||
[InlineEditor]
|
||||
[SerializeField] private AudioDatabase database;
|
||||
|
||||
[BoxGroup("Settings")]
|
||||
[MinValue(1)]
|
||||
[SerializeField] private int poolSize = 20;
|
||||
|
||||
[BoxGroup("Settings")]
|
||||
[Required]
|
||||
[SerializeField] private AudioMixerGroup defaultGroup;
|
||||
|
||||
[BoxGroup("Test")]
|
||||
[ValueDropdown(nameof(GetSampleNames))]
|
||||
[SerializeField] private string testSampleName;
|
||||
|
||||
[ShowInInspector]
|
||||
[ReadOnly]
|
||||
[BoxGroup("Runtime")]
|
||||
private int PoolCount => _pool?.Count ?? 0;
|
||||
|
||||
[ShowInInspector]
|
||||
[ReadOnly]
|
||||
[BoxGroup("Runtime")]
|
||||
private int CurrentPoolIndex => _currentIndex;
|
||||
|
||||
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 Start()
|
||||
{
|
||||
ApplyAllVolumes();
|
||||
}
|
||||
|
||||
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 ApplyAllVolumes()
|
||||
{
|
||||
SetVolume("MasterVolume", PlayerPrefs.GetFloat("MasterVolume", 80f));
|
||||
SetVolume("MusicVolume", PlayerPrefs.GetFloat("MusicVolume", 80f));
|
||||
SetVolume("VFXVolume", PlayerPrefs.GetFloat("VFXVolume", 80f));
|
||||
SetVolume("PlayerVolume", PlayerPrefs.GetFloat("PlayerVolume", 80f));
|
||||
SetVolume("UIVolume", PlayerPrefs.GetFloat("UIVolume", 80f));
|
||||
}
|
||||
|
||||
public void SetVolume(string key, float volume)
|
||||
{
|
||||
if (defaultGroup == null || defaultGroup.audioMixer == null) return;
|
||||
|
||||
// Chuyển đổi từ 0-100 sang dB (-80f đến 0f hoặc 20f tùy mixer)
|
||||
// Công thức: dB = 20 * log10(volume / 100)
|
||||
float db = volume <= 0.001f ? -80f : Mathf.Log10(volume / 100f) * 20f;
|
||||
|
||||
// Đảm bảo Parameter đã được EXPOSE trong AudioMixer với tên tương ứng (MasterVolume, MusicVolume, etc.)
|
||||
defaultGroup.audioMixer.SetFloat(key, db);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetSampleNames()
|
||||
{
|
||||
return database != null ? database.GetSampleNames() : new[] { "" };
|
||||
}
|
||||
|
||||
[Button("Play Test Sample")]
|
||||
private void PlayTestSample()
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
Debug.LogWarning("AudioManager test playback is available in Play Mode.", this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(testSampleName))
|
||||
{
|
||||
Debug.LogWarning("Choose an audio sample before testing playback.", this);
|
||||
return;
|
||||
}
|
||||
|
||||
Play(testSampleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user