using UnityEngine; using System.Collections.Generic; public class AudioManager : MonoBehaviour { public static AudioManager Instance; [System.Serializable] public class Sound { public string name; public AudioClip clip; } public List sounds = new List(); private Dictionary soundDict; private AudioSource sfxSource; public AudioClip[] enemyHitSounds; public AudioClip[] walkSteps; public AudioClip[] runSteps; void Awake() { sfxSource = gameObject.AddComponent(); sfxSource.spatialBlend = 0f; // 2D sound (no distance) sfxSource.volume = 1f; sfxSource.playOnAwake = false; // Singleton if (Instance == null) { Instance = this; //DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); return; } // AudioSource sfxSource = gameObject.AddComponent(); // Convert list -> dictionary (fast lookup) soundDict = new Dictionary(); foreach (var s in sounds) { soundDict[s.name] = s.clip; } } // Play simple SFX public void PlaySFX(string name) { if (soundDict.TryGetValue(name, out AudioClip clip)) { sfxSource.pitch = Random.Range(0.95f, 1.05f); sfxSource.volume = 1f; // force max sfxSource.PlayOneShot(clip, 1f); // second param = volume scale } } // Play at position (for hits, explosions) public void PlaySFXAtPoint(string name, Vector3 position) { if (soundDict.TryGetValue(name, out AudioClip clip)) { AudioSource.PlayClipAtPoint(clip, position); } } public void PlayEnemyHit() { if (enemyHitSounds == null || enemyHitSounds.Length == 0) return; AudioClip clip = enemyHitSounds[Random.Range(0, enemyHitSounds.Length)]; sfxSource.pitch = Random.Range(0.95f, 1.05f); // variation sfxSource.PlayOneShot(clip); } public void PlayFootstep(bool isRunning) { if ((isRunning && runSteps.Length == 0) || (!isRunning && walkSteps.Length == 0)) return; AudioClip clip = isRunning ? runSteps[Random.Range(0, runSteps.Length)] : walkSteps[Random.Range(0, walkSteps.Length)]; sfxSource.pitch = Random.Range(0.95f, 1.05f); // slightly louder for clarity float volume = isRunning ? 1f : 0.8f; sfxSource.PlayOneShot(clip, volume); } }