Utilty/SoundEmitter.cs
/// <summary>
/// A simple component that plays a sound.
/// </summary>
public sealed class SoundEmitter : Component
{
SoundHandle handle;
public SoundHandle Handle => handle;
/// <summary>
/// How long until we destroy the GameObject.
/// </summary>
[Property] public SoundEvent SoundEvent { get; set; }
/// <summary>
/// Shoulud we follow the current GameObject?
/// </summary>
[Property] public bool Follow { get; set; } = true;
public void Play()
{
handle?.Stop( 0.0f );
if ( SoundEvent == null ) return;
handle = Sound.Play( SoundEvent, Transform.Position );
}
protected override void OnStart()
{
Play();
}
protected override void OnUpdate()
{
if ( handle is null ) return;
// If we stopped playing, kill the game object
if ( handle.IsStopped )
{
GameObject.Destroy();
}
// Otherwise, let's keep updating the position
else if ( Follow )
{
handle.Position = GameObject.Transform.Position;
}
}
}
public static partial class GameObjectExtensions
{
/// <summary>
/// Creates a GameObject that plays a sound.
/// </summary>
/// <param name="self"></param>
/// <param name="sndEvent"></param>
/// <param name="follow"></param>
public static SoundHandle PlaySound( this GameObject self, SoundEvent sndEvent, bool follow = true )
{
if ( self is null )
{
Log.Warning( "null GameObject tried to play SoundEvent" );
return default;
}
if ( sndEvent is null )
{
Log.Warning( "Tried to play null SoundEvent" );
return default;
}
var gameObject = self.Scene.CreateObject();
gameObject.Name = sndEvent.ResourceName;
if ( follow ) gameObject.Parent = self;
else gameObject.Transform.World = self.Transform.World;
var emitter = gameObject.Components.Create<SoundEmitter>();
emitter.SoundEvent = sndEvent;
emitter.Play();
return emitter.Handle;
}
/// <inheritdoc cref="PlaySound(GameObject, SoundEvent, bool)"/>
public static SoundHandle PlaySound( this GameObject self, string sndPath, bool follow = true )
{
if ( ResourceLibrary.TryGet<SoundEvent>( sndPath, out var sndEvent ) )
{
return self.PlaySound( sndEvent, follow );
}
return null;
}
}