using System; using System.Collections.Generic; using System.IO; using FlaxEngine; using Console = Cabrito.Console; using Object = FlaxEngine.Object; namespace Game { public static class AudioManager { private class AudioInfo { public AudioClip[] AudioClips; public int lastAudioPlayed; } private static Random random = new Random(); private static Dictionary cachedAudioInfos = new Dictionary(); public static void PlaySound(string soundName, Actor actor, Vector3 position, float volume = 1f) { PlaySound(soundName, actor, position, volume, Vector2.One); } public static void PlaySound(string soundName, Actor actor, Vector3 position, float volume, Vector2 pitchRange) { AudioInfo audio = GetSound(soundName); if (audio.AudioClips.Length == 0) return; AudioClip audioClip; if (audio.AudioClips.Length > 1) { // Randomize selected clip while avoiding the last used clip int randomIndex = 0; for (int i = 0; i < 10; i++) { randomIndex = random.Next(audio.AudioClips.Length); if (randomIndex != audio.lastAudioPlayed) break; } audioClip = audio.AudioClips[randomIndex]; audio.lastAudioPlayed = randomIndex; } else audioClip = audio.AudioClips[0]; float pitch; if (pitchRange[0] < pitchRange[1]) // Randomized pitch pitch = (float)(pitchRange[0] + (random.NextDouble() * (pitchRange[1] - pitchRange[0]))); else pitch = pitchRange[0]; var audioSource = new AudioSource(); audioSource.Clip = audioClip; audioSource.Position = position; audioSource.Parent = actor.Parent; audioSource.Pitch = pitch; audioSource.Name = audioClip.Path; audioSource.Volume = volume; audioSource.Play(); Object.Destroy(audioSource, audioClip.Length); } private static AudioInfo GetSound(string soundName) { if (cachedAudioInfos.TryGetValue(soundName, out AudioInfo cachedAudio)) return cachedAudio; AudioInfo audio = new AudioInfo(); var workDir = Directory.GetCurrentDirectory(); var audioBasePath = Path.Combine(workDir, "Content", "Audio"); AudioClip audioClip = Content.Load(Path.Combine(audioBasePath, soundName + ".flax")); if (audioClip != null) audio.AudioClips = new AudioClip[] { audioClip }; else { // Check if this audio has multiple variations List audioClips = new List(); int index = 1; do { // TODO: make this more efficient, maybe get a list of assets and filter by name audioClip = Content.Load(Path.Combine(audioBasePath, soundName + "_var" + index + ".flax")); if (audioClip != null) audioClips.Add(audioClip); index++; } while (audioClip != null); if (audioClips.Count > 0) { audio.AudioClips = audioClips.ToArray(); } else Console.PrintError("AudioClip '" + soundName + "' not found"); } audio.lastAudioPlayed = audio.AudioClips.Length + 1; cachedAudioInfos.Add(soundName, audio); return audio; } } }