Files
sbox-public/engine/Sandbox.Engine/Scene/Components/Audio/SoundBoxComponent.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

110 lines
2.1 KiB
C#

namespace Sandbox;
/// <summary>
/// Plays a sound within a box.
/// </summary>
[Expose]
[Category( "Audio" )]
[Title( "Sound Box" )]
[Icon( "surround_sound" )]
[EditorHandle( "materials/gizmo/sound.png" )]
[Tint( EditorTint.Green )]
public sealed class SoundBoxComponent : BaseSoundComponent
{
[Property, Title( "Box Size" ), Group( "Box" )]
public Vector3 Scale
{
get => _scale;
set
{
if ( _scale == value ) return;
_scale = value;
}
}
Vector3 _scale = 50;
public BBox Inner { get; private set; }
public Vector3 SndPos { get; private set; }
protected override void DrawGizmos()
{
if ( !Gizmo.IsSelected && !Gizmo.IsHovered )
return;
Gizmo.Draw.LineThickness = 1;
Gizmo.Draw.Color = Gizmo.Colors.Green.WithAlpha( Gizmo.IsSelected ? 1.0f : 0.2f );
Gizmo.Draw.LineBBox( new BBox( Scale * -0.5f, Scale * 0.5f ) );
Gizmo.Draw.Color = Gizmo.Colors.Red.WithAlpha( 0.75f );
Gizmo.Draw.LineSphere( SndPos - LocalPosition, 10.0f );
}
protected override void OnEnabled()
{
Inner = new BBox( WorldPosition + Scale * -0.5f, WorldPosition + Scale * 0.5f );
if ( PlayOnStart )
{
StartSound();
}
}
TimeUntil TimeUntilRepeat;
public override void StartSound()
{
if ( StopOnNew )
{
SoundHandle?.Stop( 0.1f );
SoundHandle = default;
}
if ( SoundHandle.IsValid() && SoundHandle.IsPlaying ) return;
SoundHandle = Sound.Play( SoundEvent );
if ( SoundHandle.IsValid() )
{
SoundHandle.Position = SndPos;
ApplyOverrides( SoundHandle );
}
TimeUntilRepeat = Random.Shared.Float( MinRepeatTime, MaxRepeatTime );
}
protected override void OnUpdate()
{
if ( SoundHandle is not null )
{
SoundHandle.Position = SndPos;
ApplyOverrides( SoundHandle );
}
ShortestDistanceToSurface();
if ( Repeat && TimeUntilRepeat <= 0.0f )
{
StartSound();
}
}
public override void StopSound()
{
SoundHandle?.Stop( 0.1f );
}
protected override void OnDestroy()
{
base.OnDestroy();
StopSound();
}
private void ShortestDistanceToSurface()
{
var listener = Scene.FindClosestListener( Inner.Center );
SndPos = Inner.ClosestPoint( listener?.Position ?? default );
}
}