Krotox Engine › Docs › Scripting API › Graphics, UI & Audio

UI scripting API

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.

The one rule to remember

Active belongs to Entity, not to components.

Hiding and showing

WantDo
Hide an element and everything under it, and stop it receiving clickselement.Active = false;
Keep a control visible but unresponsive (greyed out)button.Interactable = false;
Fade without hidingSet 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

Screens and canvas priority

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
}

UICanvasComponent

MemberMeaning
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.
IsVisibleOnScreenWhether this canvas is currently shown.
VisibleWhenPausedStay eligible while Game.Pause() is active.
LayeredShow alongside the winning screen instead of competing (dialogs, toasts).
RenderMode, PixelsPerUnitScreenSpaceOverlay or WorldSpace.
ReferenceResolution, ReferenceWidth, ReferenceHeight, OrientationDesign resolution and orientation.

UIScreenManager has the same operations as static helpers taking an Entity: ShowScreen(screen, priority), HideScreen, IsScreenVisible, IsElementVisible, SetScreenPriority, GetScreenPriority, BringToFront, SendToBack.

World-space UI

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

Button clicks: three ways

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");
    }
}

UI component reference

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.

ComponentScriptable members
UIButtonComponentEvents OnClick, OnPressed, OnReleased, OnHoverEnter, OnHoverExit; AddListener(Action), RemoveListener(Action), RemoveAllListeners(); polling IsPressed, JustPressed, JustReleased, IsHovered, JustHovered, JustUnhovered; Interactable.
UITextComponentText, 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().
UIImageComponentTintColor, RaycastTarget.
UIRectComponentAnchorMin, AnchorMax, Pivot, Offset, Size, Scale, Rotation (radians), OrderLayer.
UISliderComponentValue (clamped when set), MinValue, MaxValue, Interactable.
UIToggleComponentIsOn, Interactable.
UIInputFieldComponentText, ReadOnly, IsFocused (read-only).
UIScrollRectComponentHorizontal, Vertical.
UIProgressBarComponentValue (0 to 1; the bar animates toward it).
UILayoutGroupComponentDirection (Horizontal, Vertical), Spacing, Padding (left, right, top, bottom).
UIGridLayoutGroupComponentCellSize, 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 name UIGridLayoutGroupComponent with GetComponent. The short aliases GridLayoutGroupComponent and GridLayoutGroup exist 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

Example: pause menu

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"); }
}

Example: HUD with score, health and game over

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);

Example: an inventory grid

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
}