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:
| Object | What it is |
|---|---|
| Panel | A box - a background, a frame to group things |
| ScrollPanel | A Panel whose contents scroll (mouse wheel or drag) |
| Label | Text |
| Button | Text you click |
| TextInput | A box the player types in |
| Image | A picture |
| ImageButton | A picture you click |
| ProgressBar | A bar filled between a min and a max - health, XP, loading |
| SliderInput | A bar the player drags to pick a number |
| Toggle | An on/off switch with a label |
And modifiers, put inside an object to change it:
| Modifier | What it does |
|---|---|
| Corner | Rounded corners |
| Border | An outline round the box - or, with ApplyTo Text, round the letters |
| Padding | Space inside the edges |
| ListLayout | Lines up the children in a row or a column |
| GridLayout | Lays the children out in a grid |
| Gradient | Shades the colour from one to another (and a middle colour) |
| AspectRatio | Keeps a width-to-height ratio on every screen |
| Scale | Draws it bigger or smaller |
| SizeLimit | Keeps its size between a min and a max |
| TextSizeLimit | Keeps 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 want | Position | Size | Anchor |
|---|---|---|---|
| Top-left corner, 200 x 50 | 0, 10, 0, 10 | 0, 200, 0, 50 | 0, 0 |
| Centred on the screen | 0.5, 0, 0.5, 0 | 0, 300, 0, 200 | 0.5, 0.5 |
| A bar across the bottom | 0, 0, 1, 0 | 1, 0, 0, 60 | 0, 1 |
| Half the parent's width | 0.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:
-- A ClientScript inside a Button
script.parent.clicked:connect(function()
print("clicked!")
end)Next: Scripting UI.