terminalCode Example

Nameplate Component with Voice Activity

calendar_today May 3, 2026 schedule ~1 min read person patrickjr verified 50

Nameplate with Voice Activity

A Razor component that displays player nameplates above characters with voice chat visualization.

Implementation

CSHARP
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent

@if (Player.IsValid() && !Player.IsLocalPlayer && !(Player.FindLocalPlayer()?.WantsHideHud ?? false))
{
    <root>
        <div class="card">
            <div class="avatar-wrap">
                @if (IsVoicePlaying)
                {
                    <div class="speaking-glow" 
                         style="opacity: @GetGlowOpacity(); transform: scale(@GetGlowScale())">
                    </div>
                }
                <div class="avatar" style="background-image: url(avatar:@Player.SteamId)"></div>
            </div>
            <label class="name">@Player.DisplayName</label>
        </div>
    </root>
}

@code
{
    [Property] public Player Player;

    Sandbox.Voice voiceComponent;
    private float _smoothedAmplitude;

    protected override void OnEnabled()
    {
        base.OnEnabled();
        voiceComponent = GameObject.Root.Components.GetInDescendantsOrSelf<Voice>();
    }

    public bool IsVoicePlaying
    {
        get
        {
            if (voiceComponent is null) return false;
            return voiceComponent.LastPlayed < 0.5f;
        }
    }

    private float GetSmoothed()
    {
        if (voiceComponent is null) return 0f;
        _smoothedAmplitude = _smoothedAmplitude.LerpTo(voiceComponent.Amplitude, Time.Delta * 10f);
        return _smoothedAmplitude;
    }

    private string GetGlowOpacity()
    {
        var s = GetSmoothed();
        return Math.Clamp(s * 4f, 0.2f, 0.9f).ToString("0.##");
    }

    private string GetGlowScale()
    {
        var s = GetSmoothed();
        return Math.Clamp(1f + s * 0.6f, 1f, 1.6f).ToString("0.##");
    }

    protected override int BuildHash() => System.HashCode.Combine(
        Network.Owner, 
        IsVoicePlaying, 
        Player.FindLocalPlayer()?.WantsHideHud ?? false, 
        Time.Now
    );
}

SCSS Example

SCSS
Nameplate {
    position: absolute;
    
    .card {
        flex-direction: column;
        align-items: center;
        
        .avatar-wrap {
            width: 64px;
            height: 64px;
            position: relative;
            
            .speaking-glow {
                position: absolute;
                width: 100%;
                height: 100%;
                border-radius: 50%;
                background: radial-gradient(circle, #4ade80, transparent);
                transition: all 0.1s ease;
            }
            
            .avatar {
                width: 100%;
                height: 100%;
                border-radius: 50%;
                background-size: cover;
                background-position: center;
            }
        }
        
        .name {
            font-size: 14px;
            font-weight: bold;
            text-shadow: 0 1px 2px black;
        }
    }
}

Key Features

  • Avatar display: Uses avatar:@SteamId URL protocol for Steam avatars
  • Voice activity: Smooth amplitude visualization with LerpTo
  • Conditional visibility: Hidden for local player and when HUD is disabled
  • Smooth transitions: CSS transitions on opacity and scale
  • String formatting: .ToString("0.##") for clean number formatting
Was this helpful?