A scene Component that centralizes table-related sound effect slots. It exposes SoundEvent properties for events like CardDraw, CardPickup, Bet, Win, etc., resolves a TableSound enum to the assigned SoundEvent, and plays the resolved sound at a world position on the client.
namespace CardGames;
/// <summary>
/// The single place to wire table sound effects. Holds one <see cref="SoundEvent"/> slot per
/// <see cref="TableSound"/>; drop a sound into a slot in the editor and that moment plays it. A slot
/// left empty simply makes its event silent, so the whole system is inert until sounds are assigned.
///
/// One instance lives in the scene (on the GameDirector object). Consumers resolve it as a cached
/// property (<see cref="CardGame.Sounds"/>, <see cref="CardHover"/>) and call <see cref="Play"/>.
/// </summary>
public sealed class GameSounds : Component
{
[Property] public SoundEvent CardDraw { get; set; }
[Property] public SoundEvent CardPickup { get; set; }
[Property] public SoundEvent CardDrop { get; set; }
[Property] public SoundEvent Bet { get; set; }
[Property] public SoundEvent Win { get; set; }
[Property] public SoundEvent Loss { get; set; }
[Property] public SoundEvent Push { get; set; }
/// <summary>The sound assigned to a given event, or null if that slot is empty.</summary>
public SoundEvent Resolve( TableSound sound ) => sound switch
{
TableSound.CardDraw => CardDraw,
TableSound.CardPickup => CardPickup,
TableSound.CardDrop => CardDrop,
TableSound.Bet => Bet,
TableSound.Win => Win,
TableSound.Loss => Loss,
TableSound.Push => Push,
_ => null,
};
/// <summary>Play a sound on this client at a world position. No-ops when the slot is unassigned.</summary>
public void Play( TableSound sound, Vector3 position )
{
if ( Resolve( sound ) is { } evt )
Sound.Play( evt, position );
}
}