S&box Wiki

UI Basics


UI entities are implemented using HTML and/or C#. Entities can be styled using SCSS, a preprocessor scripting language that is interpreted/compiled into Cascading Style Sheets (CSS). This is done out of the box.

Simple UI (static or hybrid)

For static entities without any dynamic component (static banner, simple non-changing crosshair, etc.) HTML UI might be sufficient.

You can still reference C# classes within the HTML using regular HTML-Tags. The referenced C# classes can still react dynamically to the game loop.

Example: Static crosshair w/ dynamic C# chatbox

<link rel="stylesheet" href="minimalhud.scss"> <div> <text class="title">My Minimal Game</text> <!-- A crosshair in just css --> <div style="position: absolute; left: 50%; top: 50%; background-color: white; border-radius: 10px; width: 4px; height: 4px; transform: translate( -50% -50% );"></div> <chatbox></chatbox> </div>

Advanced UI (dynamic)

For more complex scenarios (e.g. HUD's) a UI implementation using C# is recommended (and probably the only good solution).

UI components can be implemented using the abstract class Panel. This abstract class has a method override void Tick() so you can access the game loop.

UI components can either be mounted directly or through other UI Components using RootPanel.AddChild<E>();. Usually done in the constructor of the class.

To add (S)CSS to the components, simply use RootPanel.StyleSheet.Load( "/ui/PATH_TO_SCSS.scss" ); in the constructor.

Example: HUD w/ health display

Down below you can see an example from the sandbox gamemode.

SandboxHud implements the HudEntity<RootPanel> class and loads a stylesheet and all other UI components.

The Health class implements Panel and adds a bunch of stuff to the UI within its constructor. It also has access to the local player's health within the Tick-override, so the UI can be updated accordingly.

using Sandbox; using Sandbox.UI; [Library] public partial class SandboxHud : HudEntity<RootPanel> { public SandboxHud() { if ( !IsClient ) return; RootPanel.StyleSheet.Load( "/ui/SandboxHud.scss" ); RootPanel.AddChild<NameTags>(); RootPanel.AddChild<CrosshairCanvas>(); RootPanel.AddChild<ChatBox>(); RootPanel.AddChild<VoiceList>(); RootPanel.AddChild<KillFeed>(); RootPanel.AddChild<Scoreboard<ScoreboardEntry>>(); RootPanel.AddChild<Health>(); RootPanel.AddChild<InventoryBar>(); RootPanel.AddChild<CurrentTool>(); RootPanel.AddChild<SpawnMenu>(); } }

Source: sandbox - SandboxHud.cs

using Sandbox; using Sandbox.UI; using Sandbox.UI.Construct; public class Health : Panel { public Label Label; public Health() { Label = Add.Label( "100", "value" ); } public override void Tick() { var player = Local.Pawn; if ( player == null ) return; Label.Text = $"{player.Health.CeilToInt()}"; } }

Source: sandbox - Health.cs

Troubleshooting Panels

If a panel is not behaving as expected you can troubleshoot it using the Panel Inspector. First, in the S&box editor, make sure the Panel Inspector is enabled by ticking View->Panels.


If you run the game in the editor you will then be able to inspect panels in real-time.