Razor UI component for the HUD layer. Declares a HudCanvas child and exposes editable effect properties (tint, glow, scanlines, HDR exponents), lookup helpers to get the scene HudLayer or sections, and some computed gains.
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent
@namespace Sandbox
<root>
<HudCanvas @ref="Canvas" Layer=@this />
</root>
@code
{
/// <summary>
/// The HUD colour when nothing has set one, also what the HUD panels fall back to without a layer
/// </summary>
public static readonly Color DefaultTint = new Color( 0.97f, 0.77f, 0.302f );
/// <summary>
/// Colour multiplied into every HUD element
/// </summary>
[Property] public Color Tint { get; set; } = DefaultTint;
/// <summary>
/// HDR color exponent for highlighted HUD elements like digits or selected hotbar slots
/// </summary>
[Property, Group( "Effects" ), Range( 0, 6 )] public float DigitExponent { get; set; } = 0.75f;
/// <summary>
/// HDR color exponent for regular HUD text
/// </summary>
[Property, Group( "Effects" ), Range( 0, 6 )] public float TextExponent { get; set; } = 0.16f;
/// <summary>
/// HDR multipliers from <see cref="DigitExponent"/> and <see cref="TextExponent"/>
/// </summary>
public float DigitGain => MathF.Pow( 2, DigitExponent );
public float TextGain => MathF.Pow( 2, TextExponent );
[Property, Group( "Effects" ), Range( 0, 1 )] public float GlowStrength { get; set; } = 0.22f;
[Property, Group( "Effects" ), Range( 0, 48 )] public float GlowRadius { get; set; } = 20;
[Property, Group( "Effects" ), Range( 0, 1 )] public float ScanlineIntensity { get; set; } = 0.46f;
/// <summary>
/// Scanline frequency in pixels
/// </summary>
[Property, Group( "Effects" ), Range( 2, 12 )] public float ScanlinePeriod { get; set; } = 3.7f;
[Property, Group( "Effects" ), Range( 0, 1 )] public float ScanlineThickness { get; set; } = 0.55f;
[Property, Group( "Effects" ), Range( 0, 1 )] public float ScanlineSoftness { get; set; } = 0.04f;
public HudCanvas Canvas { get; private set; }
/// <summary>
/// The scene's HUD layer. With <paramref name="create"/> it is added next to the screen panel <paramref name="from"/> lives under if there isn't one yet
/// </summary>
public static HudLayer Find( Component from, bool create = true )
{
var layer = from.Scene?.Get<HudLayer>();
if ( layer.IsValid() || !create ) return layer;
var screen = from.Components.GetInAncestorsOrSelf<ScreenPanel>();
return screen.IsValid() ? screen.GameObject.Components.GetOrCreate<HudLayer>() : null;
}
/// <summary>
/// A section of the scene's HUD layer. Hand back the previous result to skip the scene lookup while its canvas is still alive
/// </summary>
public static T FindSection<T>( Component from, T cached ) where T : HudSection, new()
=> cached?.Canvas is { } canvas && canvas.IsValid() ? cached : Find( from )?.Canvas?.Section<T>();
protected override int BuildHash() => 0;
}