Sleek — The Legacy IMGUI UI System
Sleek is Unturned's original UI framework, predating the Glazier abstraction. It defines a tree of ISleekElement widgets positioned through a scale+offset coordinate system, with event delegates for interaction. The entire UI is rebuilt every frame — widgets are created, populated, drawn, and destroyed within the same update cycle, a pattern inherited from Unity's IMGUI paradigm.
Source code location: SDG.Glazier/Sleek.cs, GlazierElementBase.cs, SleekWrapper.cs, SleekWindow.cs, SleekBox.cs, SleekButton.cs, SleekLabel.cs, SleekScrollBox.cs
ISleekElement Interface
ISleekElement is the root of the entire widget hierarchy. Every UI element — boxes, buttons, labels, images, sliders, fields, scroll views — implements this interface. It defines:
Position and size use a dual-coordinate system of scale (0.0–1.0 fraction of parent) and offset (absolute pixel count):
csharp
float PositionOffset_X, PositionOffset_Y; // Pixel offset from parent origin
float PositionScale_X, PositionScale_Y; // Fraction of parent size
float SizeOffset_X, SizeOffset_Y; // Pixel size adjustment
float SizeScale_X, SizeScale_Y; // Fractional size of parentThe final position is parent_size * scale + offset. For example, an element with PositionScale_X = 0.5 and PositionOffset_X = -50 centers itself with a 50-pixel leftward adjustment.
Layout properties control automatic child arrangement:
UseManualLayout— enables manual scale/offset positioning (default true)UseChildAutoLayout— set toESleekChildLayout.VerticalorHorizontalfor automatic stackingChildPerpendicularAlignment— Center, Top, or Bottom alignment for childrenExpandChildren— fills available space across childrenChildAutoLayoutPadding— gap between auto-laid-out children in pixelsIgnoreLayout— excludes an element from auto-layout calculations
Visibility and hierarchy:
IsVisible— hides without removing from the treeParent— read-only parent referenceAddChild,RemoveChild,RemoveAllChildren— tree manipulationFindIndexOfChild,GetChildAtIndex,GetChildCount— child enumeration
Transform animation:
csharp
void AnimatePositionOffset(float x, float y, ESleekLerp lerp, float time);
void AnimatePositionScale(float x, float y, ESleekLerp lerp, float time);
void AnimateSizeOffset(float x, float y, ESleekLerp lerp, float time);
void AnimateSizeScale(float x, float y, ESleekLerp lerp, float time);Each animate method uses an ESleekLerp (Accelerate, Decelerate, or Linear) over a duration in seconds. The ISleekElement.IsAnimatingTransform property and isTransformDirty flag track animation state.
Utility:
ViewportToNormalizedPosition— converts viewport coords to 0-1 normalized spaceGetNormalizedCursorPosition— returns cursor position in 0-1 normalized spaceGetAbsoluteSize— returns pixel size of the elementSetAsFirstSibling— reorders element to the top of its parent's children
GlazierElementBase — Abstract Implementation
GlazierElementBase is the concrete abstract base for all IMGUI-style elements. It implements ISleekElement and provides:
- Field storage for all position/offset/scale properties with
ValidateNotDestroyedguards - The complete transform animation engine with per-axis lerp fields:
- Four sets of
from/to/time/methodfields for position offset, position scale, size offset, and size scale - Each axis pair has independent lerp tracking
- Four sets of
isTransformDirtyflag set whenever a position or size property changesSideLabelsupport — creates aISleekLabelattached to a specified side of the element
SleekWrapper — Widget Composition
SleekWrapper is a proxy class that wraps a single ISleekProxyImplementation (created by Glazier.Get().CreateProxyImplementation(this)). It delegates every ISleekElement method to the underlying implementation. This indirection allows composite widgets — such as SleekServer, SleekInventory, SleekCharacter — to inherit from SleekWrapper and compose multiple primitive elements without inheriting from a specific glazier implementation's base class.
Key design points:
GetProxyImplementation()returns the innerISleekProxyImplementationfor advanced accessOnUpdate()andOnDestroy()virtual methods called by the proxy during its lifecycleValidateNotDestroyed()conditional compile-time guard prevents use-after-free underVALIDATE_SLEEK_PROXY_USE_AFTER_DESTROY
SleekWindow — Root Element
SleekWindow extends SleekWrapper and serves as the root of the entire UI tree. It is assigned to Glazier.Get().Root. Every visible element is a descendant of this root.
SleekWindow manages cursor state:
csharp
public bool showCursor;
public bool isEnabled;
public bool drawCursorWhileDisabled;
public bool showTooltips;The ShouldDrawCursor property gates cursor rendering. The isCursorLocked property implements a two-frame debounce to prevent macOS angle snap issues when re-locking the cursor. The OnUpdate() method sets Cursor.visible = false and toggles Cursor.lockState between Locked and None based on ShouldDrawCursor.
The constructor sets SizeScale_X = 1 and SizeScale_Y = 1, making the root fill the entire screen.
Interface Hierarchy for Primitive Widgets
The interface hierarchy builds on ISleekElement with specialized contracts:
ISleekLabel : ISleekElement—Text,FontStyle,TextAlignment,ESleekFontSize,TextColor,AllowRichTextISleekBox : ISleekLabel, ISleekWithTooltip— addsBackgroundColorISleekButton : ISleekElement, ISleekLabel, ISleekWithTooltip— addsOnClicked/OnRightClickedevents,BackgroundColor,IsClickable,IsRaycastTargetISleekScrollView : ISleekElement—ScaleContentToWidth/Height,ContentScaleFactor,ReduceWidthWhenScrollbarVisible,VerticalScrollbarVisibilityISleekSlider : ISleekElement—Orientation,Value,MinValue,MaxValue,OnValueChangedISleekToggle : ISleekElement—Value,IsInteractable,OnValueChangedISleekField : ISleekElement—Text,PlaceholderText,MaxLength,IsMultiline,OnTextChanged,OnTextSubmittedISleekImage : ISleekElement—Texture,TintColor,ShouldDestroyTextureISleekSprite : ISleekElement—Sprite,TintColor,DrawMethod(sliced, tiled, stretched)ISleekConstraintFrame : ISleekElement—ESleekConstraintfor aspect-ratio locking
Event Handling Pattern
Sleek uses C# events for user interaction. Widgets expose events as delegates:
csharp
public delegate void ClickedButton(ISleekElement button);
public delegate void ClickedMouse();
public delegate void MovedMouse(float x, float y);Parent widgets subscribe to child events in the constructor or OnUpdate:
csharp
button.OnClicked += OnClickedButton;
toggle.OnValueChanged += OnValueToggled;The Glazier implementation (IMGUI, uGUI, or UIToolkit) translates the underlying input system into these delegate invocations. This keeps the Sleek layer input-system-agnostic.
The Scale+Offset Coordinate System
The core positioning formula for any element is:
x = parent_width * PositionScale_X + PositionOffset_X
y = parent_height * PositionScale_Y + PositionOffset_Y
width = parent_width * SizeScale_X + SizeOffset_X
height = parent_height * SizeScale_Y + SizeOffset_YThis system has two major advantages:
- Resolution independence — Layouts defined in scale units (e.g.,
SizeScale=0.5) automatically adapt to any screen resolution - Pixel-perfect adjustment — Offset values allow fine-tuning without affecting proportional layout
For example, a button centered horizontally with a fixed 200px width and 30px height would use:
PositionScale_X = 0.5, SizeOffset_X = -200, SizeScale_X = 0SizeOffset_Y = 30
The UseManualLayout = false mode switches to auto-layout, where only SizeOffset_X and SizeOffset_Y are meaningful (overriding auto-calculated sizes through UseWidthLayoutOverride and UseHeightLayoutOverride).
