UI/GameOverlay.razor

A Razor UI component that displays the current music track info and a mute control. It shows title and artist, toggles music mute via a ConVar, updates a Mixer volume, and expands the track info briefly when a new track is played.

Native Interop
@using Machines.UI
@using Machines.GameModes
@using Machines.Events
@using Machines.Systems
@using Sandbox;
@using Sandbox.Audio
@using Sandbox.UI;
@inherits PanelComponent
@namespace Machines
@implements IMusicTrackChanged

@{
    var inGame = BaseGameMode.Current.IsValid();
}
<root>
    <div class="mute @(MuteMusic ? "active" : "") @(Expanded ? "expanded" : "") @(inGame ? "in-game" : "menu")">
        <InputHint Dark=@(!inGame) Action="Mute" />
        <Label class="icon">@(MuteMusic ? "🔇" : "🔊")</Label>
        <div class="track">
            <Label class="track-title">@_title</Label>
            @if (!string.IsNullOrWhiteSpace(_artist))
            {
                <Label class="track-artist">@_artist</Label>
            }
        </div>
    </div>
</root>

@code
{
    // How long the track info stays expanded before retracting.
    private const float DisplayDuration = 5f;

    [ConVar("machines.music.mute", ConVarFlags.Saved)]
    public static bool MuteMusic { get; set; } = false;

    private Mixer _musicMixer;

    private string _title;
    private string _artist;
    private RealTimeSince _trackShownAt = DisplayDuration;

    private bool Expanded => _trackShownAt < DisplayDuration;

    protected override int BuildHash() => System.HashCode.Combine(MuteMusic, BaseGameMode.Current.IsValid(), Expanded, _title, _artist);

    protected override void OnStart()
    {
        _musicMixer = Mixer.FindMixerByName("Music");
        _musicMixer.Volume = MuteMusic ? 0 : 1;
    }

    protected override void OnFixedUpdate()
    {
        if (Input.Pressed("Mute"))
        {
            MuteMusic = !MuteMusic;
            _musicMixer?.Volume = MuteMusic ? 0 : 1;
        }
    }

    public void OnMusicTrackChanged(MusicTrack track)
    {
        _title = track.Title;
        _artist = track.Artist;
        _trackShownAt = 0f;
    }
}