Krotox Engine › Docs › Scripting API › Graphics, UI & Audio
Driving Krotox UI from C#: showing and hiding elements, switching screens with canvas priority, handling button clicks three ways, the scriptable members of every UI control, and complete pause-menu and HUD controllers.
How the UI system is put together (canvases, anchors, layout, screens) is in Game UI: canvases, layout & screens. This page is the scripting side.
Active belongs to Entity, not to components.
public Entity PauseMenu;, not as UIImageComponent.button.Entity.Active = false;.Active = false;.| Want | Do |
|---|---|
| Hide an element and everything under it, and stop it receiving clicks | element.Active = false; |
| Keep a control visible but unresponsive (greyed out) | button.Interactable = false; |
| Fade without hiding | Set the Color / TintColor alpha, and turn RaycastTarget off so the invisible image stops blocking clicks. |
public Entity StartButton;
void HideStart() { if (StartButton != null && StartButton.IsValid()) StartButton.Active = false; }
var image = GetComponent<UIImageComponent>();
image.TintColor = new Vector4(1, 1, 1, 0.0f); // fully transparent
image.RaycastTarget = false; // and click-through
Each canvas is a screen; only the canvases sharing the highest RenderOrder are shown. Show a higher-priority canvas to cover the HUD, hide it to reveal the HUD again.
public Entity HudCanvas; // RenderOrder 0
public Entity PauseCanvas; // RenderOrder 10, Visible When Paused, inactive in the scene
void OpenPause()
{
Game.Pause();
PauseCanvas.GetComponent<UICanvasComponent>().Show(); // the HUD is now hidden
}
void ClosePause()
{
PauseCanvas.GetComponent<UICanvasComponent>().Hide(); // the HUD is visible again
Game.Resume();
}
void OnUpdate(float ts)
{
if (!HudCanvas.GetComponent<UICanvasComponent>().IsVisibleOnScreen)
return; // skip HUD work while covered
}
| Member | Meaning |
|---|---|
RenderOrder / Priority, SetPriority(int) | Screen priority (one value, two names). |
Show() / Hide() | Set the canvas entity's Active. |
BringToFront() / SendToBack() | One above the highest (or below the lowest) other canvas. |
IsVisibleOnScreen | Whether this canvas is currently shown. |
VisibleWhenPaused | Stay eligible while Game.Pause() is active. |
Layered | Show alongside the winning screen instead of competing (dialogs, toasts). |
RenderMode, PixelsPerUnit | ScreenSpaceOverlay or WorldSpace. |
ReferenceResolution, ReferenceWidth, ReferenceHeight, Orientation | Design resolution and orientation. |
UIScreenManager has the same operations as static helpers taking an Entity: ShowScreen(screen, priority), HideScreen, IsScreenVisible, IsElementVisible, SetScreenPriority, GetScreenPriority, BringToFront, SendToBack.
var canvas = healthBar.GetComponent<UICanvasComponent>();
canvas.RenderMode = CanvasRenderMode.WorldSpace;
canvas.PixelsPerUnit = 200f;
healthBar.Translation = enemy.Translation + new Vector3(0, 1.5f, 0); // follow the enemy
public class MenuButtons : Entity
{
private UIButtonComponent m_Button;
// 1. Subscribe to C# events (best for code-driven UI)
public override void OnAwake()
{
m_Button = GetComponent<UIButtonComponent>();
m_Button.OnClick += OnPlayClicked;
m_Button.OnHoverEnter += () => Log.Info("Hovered");
}
private void OnPlayClicked() { SceneManager.LoadScene("Scenes/Level1.ktx"); }
// 2. Name this method in the Button's "On Click" field in the inspector
public void OnSettingsClicked() { /* ... */ }
// 3. Poll the state every frame
void OnUpdate(float ts)
{
if (m_Button.JustPressed) Log.Info("Pressed this frame");
}
}
Every drawable UI component has a read-only IsVisibleOnScreen. Setting a value from script takes effect on the next UI frame and does not call the inspector's *On Value Changed* method.
| Component | Scriptable members |
|---|---|
UIButtonComponent | Events OnClick, OnPressed, OnReleased, OnHoverEnter, OnHoverExit; AddListener(Action), RemoveListener(Action), RemoveAllListeners(); polling IsPressed, JustPressed, JustReleased, IsHovered, JustHovered, JustUnhovered; Interactable. |
UITextComponent | Text, Color, FontSize, Kerning, LineSpacing, Alignment (0 left, 1 centre, 2 right), VAlignment (0 top, 1 middle, 2 bottom), WordWrap, BestFit, MinFontSize, MaxFontSize, Bold, Italic, FitRectToContent(). |
UIImageComponent | TintColor, RaycastTarget. |
UIRectComponent | AnchorMin, AnchorMax, Pivot, Offset, Size, Scale, Rotation (radians), OrderLayer. |
UISliderComponent | Value (clamped when set), MinValue, MaxValue, Interactable. |
UIToggleComponent | IsOn, Interactable. |
UIInputFieldComponent | Text, ReadOnly, IsFocused (read-only). |
UIScrollRectComponent | Horizontal, Vertical. |
UIProgressBarComponent | Value (0 to 1; the bar animates toward it). |
UILayoutGroupComponent | Direction (Horizontal, Vertical), Spacing, Padding (left, right, top, bottom). |
UIGridLayoutGroupComponent | CellSize, Spacing, Padding, StartCorner, StartAxis, ChildAlignmentX, ChildAlignmentY, Constraint (Flexible, FixedColumnCount, FixedRowCount), ConstraintCount. |
UICanvasScalerComponent, UISafeAreaComponent, UIContentSizeFitterComponent, UIMaskComponent and UINavigationComponent have no script properties yet: configure them in the inspector, and use HasComponent, AddComponent and RemoveComponent from code.
Use the full nameUIGridLayoutGroupComponentwithGetComponent. The short aliasesGridLayoutGroupComponentandGridLayoutGroupexist in ScriptCore but are not found, because components are matched by exact type name.
Rich text in UITextComponent.Text: <b>…</b>, <i>…</i> and <color=#RRGGBB>…</color> (or #RRGGBBAA). Tags nest and work with wrapping, best fit and alignment. Anything else that looks like a tag is drawn as written.
m_Label.Text = quot;<color=#9EDA23>+{points}</color> points"; m_Label.FitRectToContent(); // resize the rect to the new text
using KrotoxEngine;
public class PauseMenuController : Entity
{
[Header("UI")]
public Entity PauseMenuRoot; // the panel holding all pause UI
public Entity ResumeButton;
public Entity RestartButton;
public Entity QuitButton;
public override void OnAwake()
{
GetComponent<UICanvasComponent>().VisibleWhenPaused = true;
ResumeButton.GetComponent<UIButtonComponent>().OnClick += Resume;
RestartButton.GetComponent<UIButtonComponent>().OnClick += Restart;
QuitButton.GetComponent<UIButtonComponent>().OnClick += QuitToMenu;
}
void OnCreate() { PauseMenuRoot.Active = false; }
void OnUpdate(float ts)
{
if (Input.IsKeyPressed(KeyCode.Escape))
{
if (Game.IsPaused) Resume();
else Pause();
}
}
public void Pause() { Game.Pause(); PauseMenuRoot.Active = true; }
public void Resume() { Game.Resume(); PauseMenuRoot.Active = false; }
public void Restart() { Game.Resume(); SceneManager.ReloadCurrentScene(); }
public void QuitToMenu() { Game.Resume(); SceneManager.LoadScene("Scenes/MainMenu.ktx"); }
}
using KrotoxEngine;
public class HUDController : Entity
{
public static HUDController Instance { get; private set; }
public Entity ScoreLabel;
public Entity HealthBar; // has a UIProgressBarComponent
public Entity GameOverPanel;
public Entity RetryButton;
private UITextComponent m_Score;
private UIProgressBarComponent m_Health;
private int m_Points;
public override void OnAwake()
{
Instance = this;
m_Score = ScoreLabel.GetComponent<UITextComponent>();
m_Health = HealthBar.GetComponent<UIProgressBarComponent>();
RetryButton.GetComponent<UIButtonComponent>().OnClick += () => SceneManager.ReloadCurrentScene();
}
void OnCreate()
{
GameOverPanel.Active = false;
AddScore(0);
}
public void AddScore(int points)
{
m_Points += points;
m_Score.Text = quot;SCORE {m_Points:D6}";
}
public void SetHealth(float ratio) { m_Health.Value = ratio; } // 0 to 1, animates smoothly
public void ShowGameOver() { GameOverPanel.Active = true; }
}
// From anywhere else:
HUDController.Instance.AddScore(100);
public Entity InventoryPanel; // has a UIGridLayoutGroupComponent
public Prefab SlotPrefab;
void BuildInventory(int slots)
{
var grid = InventoryPanel.GetComponent<UIGridLayoutGroupComponent>();
grid.CellSize = new Vector2(96, 96);
grid.Constraint = GridConstraint.FixedColumnCount;
grid.ConstraintCount = 4;
for (int i = 0; i < slots; i++)
Instantiate(SlotPrefab).Parent = InventoryPanel; // the grid arranges them
}