Exercise 7 — Screen Flow
GAME 1303-001 · Unity 6.x · Week 10 — Tuesday, October 27
In class, 10:30 – 11:45 · 2 points · Submit by end of class
The skill
A prototype opens straight into gameplay. A game has a front door.
Today you build all five screens your game needs, wire them into a flow the player can't get stuck in, and bind the HUD to real values. This is the single change that makes a project stop reading as coursework.
The design skill underneath is subtraction. Every element on your HUD costs the player attention, permanently, for the entire runtime. The question for each one is not "is this useful?" but:
What does the player do differently because this is on screen?
If the answer is nothing, it is costing you attention and returning nothing. Cut it.
By the end of the block you will have: title, HUD, pause, win, and lose — working, navigable both ways, restyled, with one element deliberately removed.
This feeds Milestone 4 — Screen Layout (Week 11), next week. Build it on your own game, not a sandbox.
What you need
- Your own game project
HelperScripts.unitypackageimported — you needUIManager,GameUI.uxml, andGameUI.uss
We use UI Toolkit, not uGUI Canvas. No Canvas, no RectTransform, no Text components. The milestone requires it.
Part 1 — Get the five screens running (20 min)
1. Set up the document
Create an empty GameObject named UI. Add:
| Component | Setting |
|---|---|
| UI Document | Source Asset → GameUI.uxml · Panel Settings → create a new one if prompted |
| UIManager | The helper script |
On UIManager, leave playerHealth and score empty — it finds them by tag. Set startAtTitle ✔.
2. Press Play
You should get a title screen. Click START and gameplay begins.
If nothing appears, check the UIDocument has a Panel Settings asset assigned — a missing one renders nothing with no error, and it catches everybody once.
3. Verify the flow
Walk the whole thing:
- Title → START → gameplay
- Esc → pause → RESUME → back to the same game state
- Pause → RESTART → level reloads
- Reach your goal → win screen
- Die → lose screen
- Every screen → QUIT TO TITLE → title
Click every button. A button that does nothing is a dead end, and dead ends cost a point in the milestone. The helper wires nine uniquely-named buttons; if one does nothing, its name in the UXML no longer matches the one in UIManager.
✅ Checkpoint 1 — all five screens reachable, every button responds, no dead ends.
Part 2 — Make the HUD live (15 min)
4. Wire real data
The HUD must read from your actual game, not show a fixed number.
- Your player needs a
Healthcomponent and thePlayertag. - Your scene needs a
Scorecomponent if you're tracking score.
UIManager subscribes to Health.OnHealthChanged and Score.OnScoreChanged automatically. Take damage — the bar should move.
A HUD that looks right in a screenshot but doesn't move during play is a hard-coded HUD, and that is exactly what the milestone checks.
5. Test it under pressure
Play until you nearly die. Can you read the health bar while dodging? Test it over the busiest part of your level, not an empty corner. Most HUDs are designed against a blank background and become invisible in play.
✅ Checkpoint 2 — health bar and score change during play.
Part 3 — Restyle it (25 min)
The starter UI is deliberately plain. Shipping it unchanged loses the design point here and in the milestone.
6. Open GameUI.uss and change the accent
At the top of .root:
--game-accent: rgb(255, 200, 60);
Change it to your game's colour. That one line restyles every primary button and the combo counter. Start here — it's the highest-return edit in the file.
7. Change the type
.root { -unity-font-definition: url("project://database/Assets/Art/YourFont.ttf"); }
Type does more for perceived polish than any other single change. A free game font from Google Fonts, imported and assigned, will make your UI look deliberate.
Then adjust .title's font-size and letter-spacing. Wide letter-spacing on a title reads as considered; default spacing reads as untouched.
8. Use UI Builder for layout
Window → UI Toolkit → UI Builder, open GameUI.uxml.
UI Toolkit uses flexbox, not anchors: flex-direction, justify-content, align-items. If you know CSS, you already know this. If you don't, the three properties above cover 90% of what you need.
Rules that are actually graded:
- Nothing critical within 5% of the screen edge. The
.hud-top-leftand.hud-top-rightclasses already do this — don't undo it. - One font, one button style, one spacing rhythm across all five screens.
- Contrast tested against your busiest background.
9. Put the controls on the title screen
.controls already exists in the UXML. Fill it in with your real controls.
This single label is worth real points in the Week 15 build rubric, because it is the difference between a stranger playing your game and a stranger closing it.
✅ Checkpoint 3 — accent, type, and layout deliberately changed; controls listed on the title screen.
Part 4 — Cut one element (10 min)
10. Justify every HUD element
List everything on your HUD. For each, answer in writing: what does the player do differently because this is on screen?
| Element | What changes because of it |
|---|---|
| Health bar | I retreat when it's low |
| Score | ...nothing, actually. I never look at it mid-play. |
| Combo | I keep chaining to hold it |
| Timer | I skip the optional room |
11. Delete the weakest one
There is always one. Remove it from the UXML.
Then play. The screen will feel better — cleaner, calmer, easier to read at speed. That feeling is the entire lesson of this exercise.
If an element is genuinely needed but only sometimes, consider showing it only then: a score that appears for two seconds when it changes costs nothing the rest of the time.
12. Write your notes
Docs/Ex07_notes.txt:
Screens: title, HUD, pause, win, lose — all reachable both directions.
Restyle:
accent rgb(255,200,60) -> rgb(90,200,255) (matches my ice theme)
font default -> "Silkscreen" (pixel, matches 32px sprites)
title 64px, letter-spacing 6 -> 48px, letter-spacing 12
HUD justification:
health bar -> I retreat when it's low. KEPT
score -> nothing. Never looked at it in play. CUT
dash icon -> I wait for it before committing. KEPT
What I cut and why:
The score label. I played five minutes watching for when I'd look
at it and I never did — my game isn't about score, it's about
surviving the room. Cutting it left the top-right corner empty, so
I moved the dash cooldown icon there where I actually look.
Readability: tested over the lit corridor (my brightest area). White
text vanished, so HUD text now has a 2px black shadow.
✅ Checkpoint 4 — one element cut with a justification, readability tested over the busiest area.
Part 5 — Build and submit (5 min)
13. Build into MyGameName/PC_Builds/Ex07/, then submit
Zip as lastname_ex07.zip: the build, five screenshots (one per screen), and Docs/Ex07_notes.txt.
Canvas → Assignments → Exercise 7.
Rubric — 2 points
| Criterion | Pt | Met when |
|---|---|---|
| Implementation | 1 | Build runs · all five screens present and navigable both directions · no dead ends · pause genuinely freezes gameplay · HUD bound to live values · built in UI Toolkit |
| Design decision | 1 | Deliberately restyled — accent, type, and layout · controls on the title screen · one HUD element cut with a written justification · readability tested over the busiest area |
Troubleshooting
Nothing renders at all.
The UIDocument has no Panel Settings asset. Create one: right-click → Create → UI Toolkit → Panel Settings Asset.
A button does nothing.
Its name in the UXML doesn't match the string in UIManager.WireButtons(). Names must be unique — Q<Button>() returns only the first match, so two buttons sharing a name leaves the second dead.
The game runs behind the title screen.
startAtTitle sets Time.timeScale = 0. If your movement uses unscaled time it will keep going. Use Time.deltaTime, not Time.unscaledDeltaTime, for gameplay.
Pause doesn't stop anything.
GameStateManager.Pause() sets timeScale = 0. Anything driven by Update() with unscaledDeltaTime, or by coroutines using WaitForSecondsRealtime, ignores it.
The health bar doesn't move.
Your player needs the Player tag and a Health component, or assign playerHealth on UIManager directly.
My USS changes don't show.
UI Toolkit caches. Close and reopen UI Builder, or toggle the UIDocument component off and on.
Everything is enormous / tiny on another resolution.
Panel Settings → Scale Mode → Scale With Screen Size, reference resolution 1920×1080.
If you finish early
- Add a hover sound to buttons:
SoundPlayer.Play("hover")from aMouseEnterEvent. - Add a transition — fade a black overlay between screens. Ten lines of USS
transition-durationand it reads as far more finished. - Make the HUD diegetic: put the health information on the character instead of in the corner. It's harder, and it's the single most impressive thing you can do in this exercise.
Before next week
Week 11 is Milestone 4 — Screen Layout, 5 points, demoed live — you will be asked to navigate the full flow in front of the room. Read milestone-4-screen-layout.md and run the ⑤ Screen Layout tab of the course checklist.
If you did today's work on your own game rather than a sandbox, the milestone is mostly done.