-
Notifications
You must be signed in to change notification settings - Fork 0
GUI
Namespaces: ScavLib.gui.ugui (uGUI) | ScavLib.gui.imgui (IMGUI)
ScavLib ships two parallel GUI stacks:
-
uGUI (
ScavLib.gui.ugui) — the primary, player-facing UI. Built on Unity's UI / TextMeshPro, themeable, draggable, and able to block game-world clicks. Use this for menus your players actually interact with. -
IMGUI (
ScavLib.gui.imgui) — a lightweight debug / development immediate-mode window stack. Quick to throw together for testing, but not intended as the shipping UI for a polished mod.
Both work in the main menu and in-game. When in doubt, build player-facing features with uGUI and reserve IMGUI for debug panels.
Renamed in 0.6.0: The old
ScavLib.guiIMGUI types (MenuWindow,MenuBuilder,MenuManager) were moved intoScavLib.gui.imguiand renamed toImguiWindow,ImguiMenuBuilder,ImguiMenuManager. See the Changelog for migration notes.
Inherit UguiWindowBase and implement Build(UguiBuilder). Controls are added
once at build time, each wired to a callback — unlike IMGUI, you do not
redraw every frame.
using ScavLib.gui.ugui;
using ScavLib.util;
using UnityEngine;
public class MyModUguiMenu : UguiWindowBase
{
public override string Title => "My Mod";
public override KeyCode ToggleKey => KeyCode.F5;
protected override void Build(UguiBuilder b)
{
b.AddLabel("Player Controls");
b.AddSeparator();
b.AddButton("Heal All", () => PlayerUtil.HealAll());
b.AddToggle("God Mode", false, on =>
{
GameUtil.Log($"God mode: {on}");
});
b.AddSlider("Heal Amount", 0f, 100f, 50f, v =>
{
GameUtil.Log($"Heal amount set to {v:F0}");
});
}
}Register it in your plugin's Awake():
private void Awake()
{
UguiWindowBase.Register(new MyModUguiMenu());
}The window builds lazily the first time it is shown, then toggles with F5.
| Member | Type | Default | Description |
|---|---|---|---|
Title |
string |
— | Title bar text. An empty title hides the title bar. |
ToggleKey |
KeyCode |
KeyCode.None |
Hotkey to show/hide. None disables hotkey toggling. |
Width |
float |
Theme.Metrics.WindowDefaultSize.x (400) |
Window width. Override for a fixed width. |
Height |
float |
Theme.Metrics.WindowDefaultSize.y (300) |
Window height. Override for a fixed height. |
Theme |
UguiTheme |
UguiTheme.Default |
Visual theme. Override to reskin. |
ShowInMenu |
bool |
false |
If true, the window is also usable in the main menu (no PlayerCamera). |
DefaultDraggable |
bool |
true |
Initial draggable state. |
Draggable |
bool (read-only) |
— | Current draggable state. Change at runtime via SetDraggable. |
DefaultBlockGameInput |
bool |
true |
Initial click-blocking state. |
BlockGameInput |
bool |
— | Runtime flag. When true, a click on this window does not pass through to the game world. |
IsVisible |
bool (read-only) |
false |
Current visibility. |
Root |
RectTransform (read-only) |
— | The built window root. null until first shown. |
| Method | Description |
|---|---|
Build(UguiBuilder builder) |
Abstract. Implement to populate the window with controls. |
Show() |
Build (if needed) and show the window. |
Hide() |
Hide the window. |
Toggle() |
Toggle visibility. |
SetDraggable(bool) |
Enable/disable dragging at runtime. |
OnShow() / OnHide()
|
Optional overrides called when the window is shown/hidden. |
UguiWindowBase.Register(window) |
Static. Register a window so its hotkey is polled. Call in Awake(). |
Click-blocking: While a visible window has
BlockGameInput = true, clicking on it will not trigger world-space actions (item pickup, etc.). Clicks on empty space still pass through. Set it tofalsefor purely informational HUD overlays that should not eat input.
All controls are added inside Build(). Each returns the underlying Unity
component so you can hold a reference and update it later (e.g. an
AddProgressBar handle whose Fill you set each frame from your own code).
| Method | Returns | Description |
|---|---|---|
AddLabel(string text) |
TextMeshProUGUI |
A non-interactive text row. |
AddButton(string label, Action onClick) |
Button |
A button; onClick fires when clicked. |
AddToggle(string label, bool initial, Action<bool> onChange = null) |
Toggle |
A checkbox; onChange receives the new value. |
AddSlider(string label, float min, float max, float initial, Action<float> onChange = null) |
Slider |
A labelled slider. The label auto-updates with the current value. |
AddProgressBar(float initial01 = 0f) |
UguiPixelBar |
A pixel-snapped fill bar (0~1). Set .Fill to update. |
AddScrollView(float height) |
(ScrollRect, RectTransform) |
A vertical scroll area. Parent further content under the returned RectTransform. |
AddSeparator() |
void |
A horizontal divider row. |
AddSpace(float pixels = -1f) |
void |
Vertical empty space. Negative uses the theme's default spacing. |
Note on slider arguments: uGUI's
AddSlidertakes(label, min, max, initial)— min/max come before the initial value. This differs from IMGUI'sSlider(label, value, min, max).
protected override void Build(UguiBuilder b)
{
var hpBar = b.AddProgressBar(1f);
b.AddButton("Take 10 Damage", () =>
{
float hp = PlayerUtil.GetBrainHealth();
hpBar.Fill = Mathf.Clamp01((hp - 10f) / 100f);
});
var (scroll, content) = b.AddScrollView(120f);
// Build additional rows under `content` with another UguiBuilder if needed.
}UguiTheme is an immutable bundle of all visual/layout parameters. Use
UguiTheme.Default for the stock look (matches the game's native style), or
derive a variant with chainable With... methods. Each call returns a new
theme; the original (including Default) is never mutated.
public override UguiTheme Theme =>
UguiTheme.Default
.WithWindowSize(500f, 360f)
.WithRowSpacing(8f)
.WithTitleAlignment(UguiTheme.TitleAlign.Center);| Method | Description |
|---|---|
WithWindowSize(width, height) |
Default window size (used when Width/Height are not overridden). |
WithRowHeight(float) |
Height of each control row. |
WithRowSpacing(float) |
Gap between control rows. |
WithDefaultSpace(float) |
Default pixel size used by AddSpace(). |
WithHeaderHeight(float) |
Title bar height. |
WithContentPadding(float) / (l, r, t, b)
|
Inner padding between the window edge and the content area. |
WithPanelColor(Color) |
Fallback panel background color (header follows it). |
WithHeaderBg(Color) |
Header background color only (advanced). |
WithHiddenTitle(bool = true) |
Hide the entire title bar (highest priority). |
WithTitleAlignment(TitleAlign) |
Left / Center / Right title alignment. |
WithTitlePadding(float) / (l, r, t, b)
|
Title text padding (independent of content padding). |
Title knob priority (high → low):
HideTitle>TitleAlignment>TitlePadding. Hiding the title disables alignment and all title padding; non-Leftalignment disables left/right title padding (top/bottom still apply). Title padding and content padding are two independent sets of fields.
Font choices, nine-slice sprite names, outline distances, and checkmark/slider
pixel metrics are locked to sensible internal defaults and are not exposed
through With... methods.
The handle returned by AddProgressBar. Set Fill (clamped 0~1) to update the
bar; when backed by a sprite it snaps to whole texture pixels for a crisp,
retro look.
var bar = builder.AddProgressBar(0.5f);
bar.Fill = 0.75f;A lightweight immediate-mode window stack for debug panels. Inherit
ImguiWindow, draw controls with ImguiMenuBuilder inside DrawContent(),
and register with ImguiMenuManager. Unlike uGUI, DrawContent() runs every
frame and interactive controls are polled by return value.
using ScavLib.gui.imgui;
using ScavLib.util;
using UnityEngine;
public class MyModDebugMenu : ImguiWindow
{
public override string Title => "My Mod (Debug)";
public override KeyCode ToggleKey => KeyCode.F6;
public override float Width => 280f;
// Height defaults to 0, which enables true auto-height.
protected override void DrawContent()
{
ImguiMenuBuilder.Label($"Hunger: {PlayerUtil.GetHunger():F1}");
ImguiMenuBuilder.Separator();
if (ImguiMenuBuilder.Button("Heal All"))
PlayerUtil.HealAll();
if (ImguiMenuBuilder.Button("Max Hunger"))
PlayerUtil.Feed(100f);
}
}Register in Awake():
private void Awake()
{
ImguiMenuManager.Register(new MyModDebugMenu());
}| Property | Type | Default | Description |
|---|---|---|---|
Title |
string |
— | Title bar text. |
ToggleKey |
KeyCode |
KeyCode.None |
Hotkey to show/hide. |
Width |
float |
300f |
Window width in pixels. |
Height |
float |
0f |
0 = auto-height (resizes to content). Set a value to fix it. |
InitialPosition |
Vector2 |
Screen center | Starting position on first render. |
Layer |
int |
0 |
Render order. Lower value renders on top. |
ShowInMenu |
bool |
false |
If true, also active in the main menu. |
IsVisible |
bool (read-only) |
false |
Current visibility. |
| Method | Description |
|---|---|
DrawContent() |
Abstract. Draw the window's controls here (called every frame). |
Show() / Hide() / Toggle()
|
Visibility control. |
OnShow() / OnHide()
|
Optional overrides on open/close. |
All methods must be called from within DrawContent().
| Method | Description |
|---|---|
Label(string text) |
Non-interactive text label. |
Separator() |
Horizontal divider line. |
Space(float pixels = 8f) |
Vertical empty space. |
| Method | Returns | Description |
|---|---|---|
Button(string label) |
bool |
true on the frame it is clicked. |
Toggle(string label, bool value) |
bool |
Checkbox. Returns the new value. |
Slider(string label, float value, float min, float max) |
float |
Slider with label. Returns the new value. |
| Method | Description |
|---|---|
SliderConfig(string label, ConfigEntry<float> entry, float min, float max) |
Slider bound directly to a float config entry. |
ToggleConfig(string label, ConfigEntry<bool> entry) |
Toggle bound directly to a bool config entry. |
| Method | Description |
|---|---|
BeginHorizontal() / EndHorizontal()
|
Horizontal layout group. |
BeginScroll(ref Vector2 scrollPos) / EndScroll()
|
Scrollable area. |
private Vector2 _scroll;
protected override void DrawContent()
{
ImguiMenuBuilder.BeginScroll(ref _scroll);
foreach (var id in ItemUtil.GetAllIds())
ImguiMenuBuilder.Label(id);
ImguiMenuBuilder.EndScroll();
}ImguiMenuManager assigns a unique IMGUI window ID (starting at 9000) to each
registered window automatically. Do not assign window IDs manually.
IMGUI hotkey detection is suspended while the developer console is open, so menu toggle keys will not fire accidentally during console input.