Music/MusicPlayer.cs
using Sandbox.Audio;
namespace HC3;
public class MusicPlayer : Component
{
public MusicTrack Track
{
get => _track;
set
{
_track = value;
if ( value is null )
{
Stop();
}
else if ( handle.IsValid() )
{
Play();
}
}
}
public MusicTrack _track;
public bool IsBrokenDown
{
get => _isBrokenDown;
set
{
_isBrokenDown = value;
if ( !_isBrokenDown )
Play();
}
}
bool _isBrokenDown { get; set; }
private SoundHandle handle;
protected override void OnDisabled()
{
base.OnDisabled();
handle?.Stop();
handle = null;
}
public void SetTrack( string path )
{
ResourceLibrary.TryGet<MusicTrack>( path, out var track );
Track = track;
}
protected override void OnUpdate()
{
base.OnUpdate();
if ( !Track.IsValid() )
return;
if ( handle.IsValid() )
{
handle.Paused = !(Scene.TimeScale > 0.0f);
if ( IsBrokenDown )
{
// fade out thru distortion, like it's tape
handle.Pitch = MathX.Lerp( handle.Pitch, 0.0f, Time.Delta / 2.0f );
if ( handle.Pitch < 0.5f )
{
Stop( 1f );
}
return;
}
}
// manually starting/looping so we can keep it in time
if ( handle?.IsStopped ?? true )
{
Play();
}
}
public void Play()
{
if ( !Track.IsValid() ) return;
if ( IsBrokenDown ) return;
var sound = Track.Sound.Sounds.FirstOrDefault();
if ( sound == null ) return;
sound.Preload();
handle?.Stop();
handle = Sound.Play( Track.Sound, WorldPosition );
handle.TargetMixer = Mixer.FindMixerByName( "ParkMusic" );
// keep everything in sync globally
handle.Time = RealTime.Now % sound.Duration;
}
public void Stop( float fadeTime = 0.0f )
{
handle?.Stop( fadeTime );
handle = null;
}
}