Skip to content

Instantly share code, notes, and snippets.

@eka
Created April 30, 2024 07:10
Show Gist options
  • Save eka/b43f1f03a70e54bae572b9ca7a881b9d to your computer and use it in GitHub Desktop.
Save eka/b43f1f03a70e54bae572b9ca7a881b9d to your computer and use it in GitHub Desktop.
using System.Linq;
using Godot;
using Godot.Collections;
public partial class AudioManager : Node
{
// ** needed sounds **
// Music
// shoot
// die
// enemy die
// fuel empty
// Player Die
// Player Fuel Collected
// Player Hit
[Export] private AudioBusLayout _audioBusLayout;
[Export] private AudioStreamPlayer _musicStreamPlayer;
[Export] private int _maxPolyphony = 10;
private float _masterVolume = 0.5f;
private float _musicVolume = 1f;
private float _soundVolume = 1f;
private Dictionary<SoundResource, AudioStreamPlayer> _sfxStreamPlayers = new();
public override void _Ready()
{
GameEventsManager.Instance.GameStarted += OnGameStarted;
GameEventsManager.Instance.UpdateSoundSettings += OnUpdateSoundSettings;
GameEventsManager.Instance.PlaySfx += OnPlaySfx;
GameEventsManager.Instance.StopSfx += OnStopSfx;
GameEventsManager.Instance.PauseGame += OnGamePaused;
GameEventsManager.Instance.EmitGetSaveData(OnGetSavedData);
CallDeferred(MethodName.EmitInitialSoundSettings);
}
private void OnGamePaused()
{
foreach (var kv in _sfxStreamPlayers)
{
var sfx = kv.Key;
GetSfxPlayer(sfx).Stop();
}
}
private void OnStopSfx(SoundResource sfxSoundResource)
{
var sfxPlayer = GetSfxPlayer(sfxSoundResource);
if(sfxPlayer.Playing) sfxPlayer.Stop();
}
private void OnPlaySfx(SoundResource sfxSoundResource)
{
PlaySfx(sfxSoundResource);
}
private void PlaySfx(SoundResource sfxSoundResource)
{
var sfxPlayer = GetSfxPlayer(sfxSoundResource);
sfxPlayer.Play();
}
private AudioStreamPlayer GetSfxPlayer(SoundResource sfxSoundResource)
{
AudioStreamPlayer audioStreamPlayer;
AudioStreamPlayer player;
_sfxStreamPlayers.TryGetValue(sfxSoundResource, out player);
if (player == null)
{
audioStreamPlayer = CreateNewAudioStreamPlayer(sfxSoundResource, AudioBusIndexes.SfxBusName);
_sfxStreamPlayers.Add(sfxSoundResource, audioStreamPlayer);
AddChild(audioStreamPlayer);
}
else
{
audioStreamPlayer = player;
}
return audioStreamPlayer;
}
private AudioStreamPlayer CreateNewAudioStreamPlayer(SoundResource soundResource, string busName)
{
var audioStreamPlayer = new AudioStreamPlayer();
audioStreamPlayer.Stream = soundResource.AudioStream;
audioStreamPlayer.Bus = busName;
audioStreamPlayer.MaxPolyphony = _maxPolyphony;
return audioStreamPlayer;
}
private void OnGetSavedData(SaveData saveData)
{
_masterVolume = saveData.MasterVolume;
_musicVolume = saveData.MusicVolume;
_soundVolume = saveData.SfxVolume;
}
public override void _ExitTree()
{
GameEventsManager.Instance.GameStarted -= OnGameStarted;
// GameEventsManager.Instance.PauseGame -= OnGamePaused;
// GameEventsManager.Instance.ResumeGame -= OnGameResumed;
GameEventsManager.Instance.UpdateSoundSettings -= OnUpdateSoundSettings;
}
private void OnUpdateSoundSettings(float masterVolume, float musicVolume, float sfxVolume)
{
_masterVolume = masterVolume;
_musicVolume = musicVolume;
_soundVolume = sfxVolume;
AudioServer.SetBusVolumeDb(AudioBusIndexes.GetMasterBusIndex(), Mathf.LinearToDb(_masterVolume));
AudioServer.SetBusVolumeDb(AudioBusIndexes.GetMusicBusIndex(), Mathf.LinearToDb(_musicVolume));
AudioServer.SetBusVolumeDb(AudioBusIndexes.GetSfxBusIndex(), Mathf.LinearToDb(_soundVolume));
}
private void EmitInitialSoundSettings()
{
// GetInitialAudioLevels();
GameEventsManager.Instance.EmitInitialSoundSettings(_masterVolume, _musicVolume, _soundVolume);
}
private void GetInitialAudioLevels()
{
var masterVolumeDb = AudioServer.GetBusVolumeDb(AudioBusIndexes.GetMasterBusIndex());
var musicVolumeDb = AudioServer.GetBusVolumeDb(AudioBusIndexes.GetMusicBusIndex());
var soundVolumeDb = AudioServer.GetBusVolumeDb(AudioBusIndexes.GetSfxBusIndex());
_masterVolume = Mathf.DbToLinear(masterVolumeDb);
_musicVolume = Mathf.DbToLinear(musicVolumeDb);
_soundVolume = Mathf.DbToLinear(soundVolumeDb);
}
private void OnGameStarted()
{
_musicStreamPlayer.Play();
}
public static class AudioBusIndexes
{
public const string SfxBusName = "Sfx";
public const string MusicBusName = "Music";
public const string MasterBusName = "Master";
public static int GetMasterBusIndex()
{
return GetBusIndex(MasterBusName);
}
public static int GetMusicBusIndex()
{
return GetBusIndex(MusicBusName);
}
public static int GetSfxBusIndex()
{
return GetBusIndex(SfxBusName);
}
private static int GetBusIndex(string busName)
{
return AudioServer.GetBusIndex(busName);
}
}
public class SfxSounds
{
public static string PlayerFireBlaster = "PlayerFireBlaster";
}
}
@eka
Copy link
Author

eka commented Apr 30, 2024

This is added to a scene of type Node only and added as AutoLoad in Godot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment