sas
This commit is contained in:
90
Code/Sounds/DspReverb.cs
Normal file
90
Code/Sounds/DspReverb.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using Sandbox;
|
||||
using Sandbox.Audio;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Sandbox;
|
||||
|
||||
public sealed class DSPReverb : Component, Component.ITriggerListener
|
||||
{
|
||||
[Property] public MixerHandle TargetMixer { get; set; }
|
||||
[Property] public DspPresetHandle Preset { get; set; }
|
||||
[Property] [Range(0f, 10f, 0.1f)] public float FadeDuration { get; set; } = 1f;
|
||||
[Property] public BBox Bounds { get; set; } = new BBox(Vector3.One * -100f, Vector3.One * 100f);
|
||||
|
||||
private DspProcessor _processor;
|
||||
private BoxCollider _triggerCollider;
|
||||
|
||||
private CancellationTokenSource _cts;
|
||||
|
||||
protected override void OnAwake()
|
||||
{
|
||||
base.OnAwake();
|
||||
|
||||
_triggerCollider = Components.Create<BoxCollider>();
|
||||
_triggerCollider.IsTrigger = true;
|
||||
_triggerCollider.Static = true;
|
||||
_triggerCollider.Scale = Bounds.Size;
|
||||
_triggerCollider.Center = Bounds.Center;
|
||||
}
|
||||
|
||||
public void OnTriggerEnter(Collider other)
|
||||
{
|
||||
_cts?.Cancel();
|
||||
_cts = new CancellationTokenSource();
|
||||
|
||||
if(_processor != null) { TargetMixer.Get().RemoveProcessor(_processor);}
|
||||
|
||||
_processor = new DspProcessor(Preset.Name);
|
||||
_processor.Mix = 0f;
|
||||
TargetMixer.Get().AddProcessor(_processor);
|
||||
|
||||
_ = UpdateMixAsync(1f);
|
||||
}
|
||||
|
||||
private async Task UpdateMixAsync(float targetMix)
|
||||
{
|
||||
float startMix = _processor.Mix;
|
||||
float elapsed = FadeDuration * ((targetMix == 0f || startMix == 0f) ? 0f : Math.Min(startMix / targetMix, 1f));
|
||||
float lastTime = Time.Now;
|
||||
|
||||
while (elapsed < FadeDuration && !_cts.IsCancellationRequested)
|
||||
{
|
||||
await Task.FixedUpdate();
|
||||
|
||||
float delta = Time.Now - lastTime;
|
||||
elapsed += delta;
|
||||
|
||||
float t = Math.Clamp(elapsed / FadeDuration, 0f, 1f);
|
||||
_processor.Mix = Math.Clamp(startMix + (targetMix - startMix) * t, 0f, 1f);
|
||||
|
||||
lastTime = Time.Now;
|
||||
}
|
||||
|
||||
if (!_cts.IsCancellationRequested)
|
||||
{
|
||||
_processor.Mix = targetMix;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnTriggerExit(Collider other)
|
||||
{
|
||||
_cts?.Cancel();
|
||||
_cts = new CancellationTokenSource();
|
||||
|
||||
_ = UpdateMixAsync(0f).ContinueWith( (_) =>
|
||||
{
|
||||
if (_processor == null) return;
|
||||
|
||||
TargetMixer.Get().RemoveProcessor(_processor);
|
||||
_processor = null;
|
||||
} );
|
||||
}
|
||||
|
||||
protected override void DrawGizmos()
|
||||
{
|
||||
base.DrawGizmos();
|
||||
Gizmo.Draw.Color = Color.Green;
|
||||
Gizmo.Draw.LineBBox(Bounds);
|
||||
}
|
||||
}
|
||||
13
Code/Sounds/MusicPlayerInteractions.cs
Normal file
13
Code/Sounds/MusicPlayerInteractions.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Sandbox;
|
||||
|
||||
public sealed class MusicPlayerInteractions : SimpleInteractions.SimpleInteraction
|
||||
{
|
||||
[Property] public MyMusicPlayer MusicPlayer { get; set; }
|
||||
|
||||
[Rpc.Broadcast]
|
||||
protected override void OnInteract()
|
||||
{
|
||||
// Log.Info($"{Rpc.Caller.DisplayName} interacted with {this.GameObject.Name}!");
|
||||
MusicPlayer.Next();
|
||||
}
|
||||
}
|
||||
118
Code/Sounds/MyMusicPlayer.cs
Normal file
118
Code/Sounds/MyMusicPlayer.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user