User interface
A game’s menus and HUD are UI documents: text files of markup that say what is on a screen, much like a web page. A UI theme styles them. Scripts show documents, fill in their text, and answer their buttons.
UI documents
Section titled “UI documents”Make one with Create > UI > UI Document in the Assets panel. Its page is a text editor with a live preview beside it, drawn the way the game will draw it; the preview catches up a moment after you stop typing. Save it to use it in the game.
A pause menu:
<screen mode="modal" transition="fade" default-focus="resume-btn"> <Flex direction="vertical" justify="center" align="center"> <Panel padding="24" class="card"> <Flex direction="vertical" align="stretch" spacing="10" width="400"> <Label text="Paused" font-size="36"/> <Button id="resume-btn" text="Resume" height="44"/> <Button id="quit-btn" text="Leave to the title" height="44"/> </Flex> </Panel> </Flex></screen>Elements nest: layouts hold other elements, and controls are what the player sees and uses. An
element’s attributes are its settings, written in lower case with dashes (font-size,
default-focus). Give an element an id to reach it from a script.
The screen
Section titled “The screen”A document that a script shows starts with <screen>. Its mode says how it sits over what is
below:
overlay: the screens below show, and clicks pass through. A HUD.modal(the default): the screens below show, but take no input. A pause menu.opaque: the screens below are hidden. A title screen.
transition animates it in and out: fade, slide-left, slide-right, slide-up,
slide-down or scale (in-transition and out-transition set each way apart).
default-focus names the element a keyboard or gamepad starts on, so menus work without a
mouse.
Elements
Section titled “Elements”| Layouts | Flex (a row or column), Grid, Dock, Flow, Frame, Absolute |
| Containers | Panel, ScrollView |
| Text | Label, EditText, PasswordBox, NumericField |
| Buttons | Button, IconButton, ContentButton, ToggleButton, CheckBox, RadioButton, RadioGroup, ToggleSwitch |
| Values | Slider, ProgressBar, ComboBox |
| Pictures | ImageView, ColorView |
| Structure | TabView, Expander, ListView, TreeView, GridView, Spacer, Separator |
Themes
Section titled “Themes”A UI theme (Create > UI > UI Theme) is a style sheet. Rules pick elements by type, or by a
class you give them, and set how they look:
Label { text-color: #2A251F; }
.card { background: rounded-rect(#F4ECD8, radius=6, border=#2A251F, border-width=3); box-shadow: 6 8 0 rgba(42, 37, 31, 0.45);}Its page edits the sheet beside a preview, and Preview Document shows one of your documents
in it. Set the project’s theme in Project > Project Settings…, on the UI tab, as
Default UI theme. A project theme replaces the built-in one, so style everything the game
shows. An element can also carry its own style="...".
Import .ttf, .otf or .ttc fonts. The UI tab of Project Settings has the Default UI
font, and Other UI fonts for more families, which an element picks with font-family.
Showing documents from a script
Section titled “Showing documents from a script”Scripts show documents as a stack of screens, with ui:
local Pause = Guid.new("628098f1-29ea-4b5e-bdea-e6a828da27f5") -- a UI document's ID
function Game:pause() local screen = ui.push(Pause) screen:findButton("resume-btn"):onClick(function() ui.pop() end)end
function Game:showLives(lives) ui.findLabel("hud-lives"):setText("x " .. lives) ui.findProgressBar("hud-health"):setValue(0.75)endGuid kPause = Guid("628098f1-29ea-4b5e-bdea-e6a828da27f5"); // a UI document's ID
void pause(){ Screen@ screen = ui::push(kPause); screen.findButton("resume-btn").onClick(Action(this.resume));}
void resume(){ ui::pop();}
void showLives(int lives){ ui::findLabel("hud-lives").setText("x " + lives); ui::findProgressBar("hud-health").setValue(0.75f);}push(document)shows a document on top;pop()removes the top one, andback()removes it unless it is the last.replace(document)swaps the top one, andclear()empties the stack.findLabel,findButton,findProgressBar,findSlider,findTextBox,findImageandfindGroupfind an element by itsid, onuior within a screen. If there is none of that type, the result’sisValid()is false, and calls on it do nothing.- Every element can
setVisible,setEnabled,setOpacity, and animate:fadeTo,moveTo,scaleToandrotateTotake a time in seconds and an optional easing (Ease.OutBack,Ease::OutBounceand so on);pulse(peak, seconds)swells it briefly, to draw the eye. - A label has
setTextandsetTextColor; a progress barsetValuefrom 0 to 1; a slidersetValue,setRangeandonChanged; an imagesetSource. - A button’s
onClickruns on the frame after the click.
UI in the scene
Section titled “UI in the scene”Three components show a document from an entity instead.
UI Canvas shows a document on the screen while its scene is loaded, a HUD that belongs to a
level. Order puts one canvas above another. Its Scaler Mode sizes it:
ConstantPixel keeps one UI pixel to one screen pixel, and ReferenceResolution scales the
whole document as if the screen were the Reference Resolution (1920 by 1080), so it looks the
same on every display. With Render Mode RenderTexture it draws into a texture instead, for a
screen on a computer in the world.
UI Billboard floats a document over the entity, such as a name or a health bar. Offset
lifts it, and with Scale Mode Distance it shrinks as the entity gets further away, between
Min Scale and Max Scale. Billboards cannot be clicked.
UI World Panel puts a document on a flat panel in the world, Size Meters across, in the entity’s plane. With Interactive on, the player can click it.
A script reaches a component’s document through its root():
local panel = UICanvasComponent.of(self.entity):root()panel:findLabel("score"):setText("0")ViewGroup@ panel = UICanvasComponent::of(self).root();panel.findLabel("score").setText("0");UIBillboardComponent and UIWorldPanelComponent work the same way.
The loading screen
Section titled “The loading screen”A document set as Loading screen on the Startup tab of Project Settings shows while the first scene loads.