sasalka/Code/Sounds/MyMusicPlayer.cs
2025-05-25 19:14:50 +03:00

119 lines
2.3 KiB
C#

namespace Sandbox;
public sealed class MyMusicPlayer : Component
{
[Property] private List<SoundEvent> _sounds;
[Property] private List<SoundPointComponent> _speakers;
[Property] private bool PlayOnStart { get; set; } = true;
private List<int> _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<SoundEvent>("music"))
{
Log.Info(resource);
_sounds.Add(resource);
}
_speakers = GameObject.GetComponentsInChildren<SoundPointComponent>().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;
}
}