Component that manages background music playback, with separate mixers and looping players for drums and melody. It finds mixers by name, plays audio files from provided path lists, handles repeat callbacks to advance to the next clip, and can pause/resume playback.
using Sandbox;
using Sandbox.Audio;
public sealed class MusicManager : Component
{
[Property] public List<string> DrumPaths { get; set; }
[Property] public List<string> MelodyPaths { get; set; }
public Mixer MixerDrums { get; set; }
public MusicPlayer MusicDrums { get; set; }
public int DrumsNum { get; set; }
public Mixer MixerMelody { get; set; }
public MusicPlayer MusicMelody { get; set; }
public int MelodyNum { get; set; }
protected override void OnAwake()
{
base.OnAwake();
MixerDrums = Mixer.FindMixerByName( "MusicDrums" );
MixerDrums.Volume = 0.15f;
MixerMelody = Mixer.FindMixerByName( "MusicMelody" );
MixerMelody.Volume = 0.15f;
Restart();
}
public void Restart()
{
//MusicDrums?.Stop();
//MusicDrums?.Dispose();
//MusicMelody?.Stop();
//MusicMelody?.Dispose();
//DrumsNum = 0;
//_drumProgressionCounter = 0;
//PlayDrums( 0 );
//PlayMelody( 0 );
}
void OnDrumsRepeat()
{
//_drumProgressionCounter++;
if ( DrumsNum < DrumPaths.Count - 1 )
PlayDrums( DrumsNum + 1 );
}
void OnMelodyRepeat()
{
if ( MelodyNum < MelodyPaths.Count - 1 )
PlayMelody( MelodyNum + 1 );
}
void PlayDrums( int num )
{
if ( num >= DrumPaths.Count )
return;
//Log.Info( $"PlayDrums: music/song1/drums{num}.wav" );
MusicDrums?.Stop();
MusicDrums?.Dispose();
//MusicDrums = MusicPlayer.Play( FileSystem.Mounted, $"music/song1/drums{num}.wav" );
MusicDrums = MusicPlayer.Play( FileSystem.Mounted, DrumPaths[num] );
MusicDrums.Repeat = true;
MusicDrums.ListenLocal = true;
MusicDrums.OnRepeated = OnDrumsRepeat;
MusicDrums.TargetMixer = MixerDrums;
DrumsNum = num;
}
void PlayMelody( int num )
{
if ( num >= MelodyPaths.Count )
return;
MusicMelody?.Stop();
MusicMelody?.Dispose();
//MusicMelody = MusicPlayer.Play( FileSystem.Mounted, $"music/song0/melody{num}.wav" );
MusicMelody = MusicPlayer.Play( FileSystem.Mounted, MelodyPaths[num] );
MusicMelody.Repeat = true;
MusicMelody.ListenLocal = true;
MusicMelody.OnRepeated = OnMelodyRepeat;
MusicMelody.TargetMixer = MixerMelody;
MelodyNum = num;
}
public void SetPaused( bool paused )
{
if ( MusicDrums != null )
MusicDrums.Paused = paused;
if ( MusicMelody != null )
MusicMelody.Paused = paused;
}
protected override void OnUpdate()
{
base.OnUpdate();
//if ( MusicDrums != null )
//{
// Gizmo.Draw.ScreenText(
// $" Drums: {DrumsNum}/{DrumPaths.Count - 1}"
// + $"\n {DrumPaths[DrumsNum]}"
// + $"\n Duration: {MusicDrums.Duration}"
// + $"\n PlaybackTime: {MusicDrums.PlaybackTime}"
// + $"\n Repeat: {MusicDrums.Repeat}"
// + $"\n ListenLocal: {MusicDrums.ListenLocal}",
// //+ $"\n _drumProgressionCounter: {_drumProgressionCounter}",
// new Vector2( 50, 30 ) );
//}
//if ( MusicMelody != null )
//{
// Gizmo.Draw.ScreenText(
// $" Melody: {MelodyNum}/{MelodyPaths.Count - 1}"
// + $"\n {MelodyPaths[MelodyNum]}"
// + $"\n Duration: {MusicMelody.Duration}"
// + $"\n PlaybackTime: {MusicMelody.PlaybackTime}"
// + $"\n Repeat: {MusicMelody.Repeat}"
// + $"\n ListenLocal: {MusicMelody.ListenLocal}",
// new Vector2( 50, 200 ) );
//}
}
}