Design a HUD that works on phones
Where the touch controls and game menu sit on a phone, where to put status, prompts and instructions, how to fit a 320 px screen, and how to word a HUD for touch players.
Most players meet a published game on a phone held upright. The touch controls and the game menu already take part of that screen, so a HUD laid out on a desktop monitor tends to run off the edge, sit under a button or cover the action. This page lists what to check and the patterns that pass. The measurements come from an iPhone 12 mini in Safari, whose game area in portrait is 359 × 648 CSS pixels; a 320 px wide phone is the narrowest worth supporting.
Know which parts of the screen are taken
Positions here are measured from the game area's top-left corner, in CSS pixels, on that iPhone. They scale with the screen but keep these proportions.
| What | Where it sits |
|---|---|
| Game menu button | Top-left, from 8 to 56 px across and 8 to 48 px down. It is always there once the game starts, and your GUI cannot move it. |
| Movement stick (and look stick) | The bottom 159 px on its side, about the left or right half of the width. A scene with drag-to-look shows a "Drag to look" label about 183 px from the bottom. |
| Action buttons, one stick | The opposite bottom corner: up to two rows of 56 px buttons, starting 120 px from the bottom. |
| Action buttons, two sticks | One row across the middle, just above the sticks, 171 to 227 px from the bottom. |
That leaves two bands for your HUD: a top band, right of the menu button or below it, for status the player needs all the time, and a prompt band just above the controls for short messages. Keep the middle of the screen clear: that is where the player is looking, and where a reticle or the character usually is.
Put each kind of text in its place
- Always-on status (score, health, time, objective): one compact strip in the top band. Anchor it
topatposition {x: 0.5, y: 0.02}, ortopRightwith amargin. Never anchor a HUD paneltopLeftat the corner, which is under the menu button. - Prompts and feedback ("Grab", "Hit taken", "Lap 2"): in the prompt band, anchored
bottomat abouty: 0.62with two sticks ory: 0.70with one, and shown only while they matter. Hide a feedback card when its message has expired rather than leaving a default sentence up. - Instructions and long explanations: behind an Info button with a 44 px touch target, or shown for a few seconds at the start and then hidden. A phone player cannot read three lines of help and play at the same time.
- Boss bars, dialogue and menus that genuinely need the middle: show them when they apply and hide them afterwards, so the middle is empty the rest of the time.
Group the parts of one HUD in a guiPanel with layoutMode: "column" or "row" instead of placing several labels by hand. A flowing panel moves its children apart as their text grows, while separately placed labels end up on top of each other the first time a number gains a digit.
Fit the width
- Give a panel at most 288 px of fixed width, or use
widthMode: "percent". A 320 px phone leaves 288 px between 16 px margins. - Write short text for the phone. "BLUE 2 : 1 RED · 3:40" fits where "BLUEBELL 2 : 1 FOXGLOVE | 3:40" does not.
- Let the renderer wrap. Parent a
wrapTextlabel to a panel with a width, and it breaks between words. Inserting your own line breaks every N characters leaves a word alone on the last line ("frames", "pad") as soon as a number changes length. - Size bars from their panel. A health bar a script sets to a fixed 354 px still runs out of a panel the phone layout narrowed to 270 px; compute the full width from the panel you lay out for that device.
Write for the device in use
Never show a key name to a touch player. "WASD move", "Press Q to lock on" and "Click to fire" mean nothing on a phone, and they are the most common thing a desktop-built HUD gets wrong. Read input.device in a GUI script and choose the wording, and the layout, when it changes; see Player input and touch controls for what each value means.
-- On the HUD panel. Phone layout and wording; the authored desktop layout stays as it is.
local device = nil
function update(deltaTime)
local now = input.device or "keyboard"
if now == device then return end
device = now
local hint = gameObject.getObjectByName("Controls hint")
if now == "touch" then
-- Top band, centred, clear of the menu button and the controls.
gameObject.setAnchor("top")
gameObject.setGuiPosition(0.5, 0.02)
gameObject.setWidth(240)
if hint then hint.setText("Hold Rewind to undo a mistake") end
else
gameObject.setAnchor("topRight")
gameObject.setGuiPosition(1, 0)
gameObject.setWidth(284)
if hint then hint.setText("Hold R to rewind · Shift for slow motion") end
end
end
It does its work only when the device changes, so it costs nothing per frame, and it switches back when a tablet player picks up a keyboard. Touch wording names the on-screen button ("Hold Rewind"), which matches the label the player sees. In a multiplayer room, keep this in a GUI script: input.device reads nil in scene, control and authority scripts.
Name the buttons
- Label every action with what it does, in a word or two: "Sword", "Rewind", "Throw". An action with no label shows its ID, and a 56 px button fits about seven characters on one line before it wraps.
- Keep the actions a player uses all the time as buttons, and move occasional ones (Reset, Training, camera options) into the actions menu with On touch: In actions menu.
- Leave no placeholder text in a published game: a label that still says "Label", a row of dashes, or a debug line such as "no authority state".
- Word solo play for players. If a multiplayer game can also be played alone, say what solo play is ("Solo drive: invite friends for tank combat") instead of an editor message, and hide it after a few seconds.
Check it on a phone before publishing
- Sign in on the phone, open the scene and start Preview. It uses the same touch controls and safe areas as the published game.
- Hold the phone upright and play for a minute. Look for text that is cut off at an edge, text under the menu button or a control, text over the middle of the screen, and any key or mouse wording.
- Open the actions menu and read every label.
- Switch to a keyboard (or a desktop browser) and check the desktop HUD is still as you authored it.
- Publish again. HUD changes reach players only in a new release; see Publish and test a game.