namespace Sandbox; public sealed class MyMusicPlayer : Component { [Property] private List _sounds; [Property] private List _speakers; [Property] private bool PlayOnStart { get; set; } = true; private List _shuffleOrder = new(); private int _shuffleIndex = 0; [Sync, Change("OnFileNameChanged")] private string FileName { get; set; } protected override void OnAwake() { base.OnAwake(); _sounds = new(); _speakers = new(); foreach (var resource in ResourceLibrary.GetAll("music")) { Log.Info(resource); _sounds.Add(resource); } _speakers = GameObject.GetComponentsInChildren().ToList(); Log.Info("speaker count: " + _speakers.Count); GenerateShuffleOrder(); } protected override void OnStart() { base.OnStart(); if (PlayOnStart) Next(); } private void GenerateShuffleOrder() { _shuffleOrder = Enumerable.Range(0, _sounds.Count).ToList(); _shuffleOrder = _shuffleOrder.OrderBy(_ => Guid.NewGuid()).ToList(); _shuffleIndex = 0; } public void Stop() { foreach (var speaker in _speakers) { speaker.StopSound(); } } [Rpc.Broadcast] public void Next() { if (_sounds.Count == 0) return; if (_shuffleIndex >= _shuffleOrder.Count) { GenerateShuffleOrder(); } int soundIndex = _shuffleOrder[_shuffleIndex]; _shuffleIndex++; FileName = _sounds[soundIndex].ResourceName; } public void OnFileNameChanged() { var currentSound = _sounds.Find((sound) => sound.ResourceName == FileName); foreach (var speaker in _speakers) { speaker.StopSound(); Log.Info(currentSound); speaker.SoundEvent = currentSound; speaker.StartSound(); } } private TimeSince _lastCheckTime; private bool _isPlaying = false; protected override void OnUpdate() { if ( _lastCheckTime < 1.0f ) return; _lastCheckTime = 0; bool isAnyPlaying = _speakers.Any(IsSpeakerPlaying); // Log.Info(isAnyPlaying); if (!_isPlaying && isAnyPlaying) { _isPlaying = true; } else if (_isPlaying && !isAnyPlaying) { _isPlaying = false; Next(); } } private static bool IsSpeakerPlaying(SoundPointComponent speaker) { var effect = speaker as ITemporaryEffect; return effect != null && effect.IsActive; } }