Skip to content

Designing UI ​

A game's on-screen UI - a coin counter, a shop, a menu - is built under UI in the Hierarchy. Every player gets their own copy when they join, and the ClientScripts inside it make it work. This page is about laying it out in KHIM Engine; Scripting UI is about driving it from code.

The pieces ​

Canvas is a screen of UI: everything else goes inside one. Inside a Canvas:

ObjectWhat it is
PanelA box - a background, a frame to group things
ScrollPanelA Panel whose contents scroll (mouse wheel or drag)
LabelText
ButtonText you click
TextInputA box the player types in
ImageA picture
ImageButtonA picture you click
ProgressBarA bar filled between a min and a max - health, XP, loading
SliderInputA bar the player drags to pick a number
ToggleAn on/off switch with a label

And modifiers, put inside an object to change it:

ModifierWhat it does
CornerRounded corners
BorderAn outline round the box - or, with ApplyTo Text, round the letters
PaddingSpace inside the edges
ListLayoutLines up the children in a row or a column
GridLayoutLays the children out in a grid
GradientShades the colour from one to another (and a middle colour)
AspectRatioKeeps a width-to-height ratio on every screen
ScaleDraws it bigger or smaller
SizeLimitKeeps its size between a min and a max
TextSizeLimitKeeps its text size between a min and a max

Right-click UI or any UI object > Insert Object to add any of them. UI itself adds New Canvas first.

Position and size ​

Every UI object has a Position and a Size, each with a scale (a share of the parent, 0 to 1) and an offset (UI points), for X and Y. And an Anchor: the point of the object that its Position places.

You wantPositionSizeAnchor
Top-left corner, 200 x 500, 10, 0, 100, 200, 0, 500, 0
Centred on the screen0.5, 0, 0.5, 00, 300, 0, 2000.5, 0.5
A bar across the bottom0, 0, 1, 01, 0, 0, 600, 1
Half the parent's width0.5, 0, ...

Scale keeps a layout right on every screen; offsets keep things a fixed size. Mix them.

Laying it out in the view ​

View > UI over the place draws the UI over the 3D view, as players will see it:

  • Click an object to select it; drag it to move; drag one of its eight handles to resize.
  • Snapping: while dragging, edges and middles snap to the parent's and to neighbours', with pink guides. Snapped to the parent's middle or edge, the Position is written as a scale, so it stays centred (or against that edge) on every screen. Hold Ctrl to drag freely.
  • Align buttons in the Inspector: Left / Centre / Right, Top / Middle / Bottom.
  • Spread children across or down: equal gaps between three or more.

Check every screen ​

At the top of the view, a chip names the screen the UI is laid out for: This view, or a device - Phone (844 x 390), Small phone, Phone upright, Tablet, Laptop, Desktop (1920 x 1080). Pick one and its screen is drawn to scale, so you can fix a layout for a phone without leaving the editor.

Phones

UI points never get smaller than the design's. A UI made for a big monitor can overlap itself on a phone: use scale for sizes, a SizeLimit so panels stop growing on big screens, and a Scale set from camera.viewportSize to shrink a whole group on small ones.

Text ​

A Label, Button or TextInput's Text section: Text, TextColor, TextSize, TextAlign (Left, Center, Right), TextWrapped, TextScaled (as big as fits the box) and Font:

  • Default - the class's own (a Button's is bold),
  • Bold,
  • Display - a heavy face for titles and key caps.

For white text over a busy world, add a Border inside the Label and set its ApplyTo to Text: an outline round the letters.

What is drawn on top ​

Objects are drawn by ZIndex, but never under what they are inside: a child is always over its parent. Among equals, later siblings cover earlier ones. Clicks go to the topmost button the same way.

Pictures ​

An Image's Image row lists KHIM's pictures and your world's uploads; drag a picture card from the Assets panel onto it, or type an asset ID. See Models, pictures and sounds.

Adding the code ​

Right-click a Canvas or any UI object > Insert Object > ClientScript. It runs once on every player, with that object as script.parent:

lua
-- A ClientScript inside a Button
script.parent.clicked:connect(function()
    print("clicked!")
end)

Next: Scripting UI.