Exercise 1 — First Playable
GAME 1303-001 · Unity 6.x · Week 1 — Tuesday, August 25
In class, 10:30 – 11:45 · 2 points · Submit by end of class
The skill
Every game is a loop of input → response. Before you can design how a game feels, you have to be able to get a thing on screen and make it answer the player. That's today.
You will also set up the project conventions you use for the next fifteen weeks. Ten minutes of folder discipline now saves hours in November.
By the end of the block you will have: a sprite on screen that moves with both keyboard and gamepad, tuned by you, running in a build.
What you need
- Unity 6.x installed via Unity Hub
HelperScripts.unitypackage— Canvas → Files → HelperScripts- One sprite. Yours, drawn in the first hour, or the provided
placeholder_character.png. A 32×32 square with a face on it is completely acceptable today. - A gamepad if you have one. Lab has a few.
Part 1 — Project setup (15 min)
1. Make your project folder first
Before you open Unity, make a folder for the whole project — not just the Unity part:
MyGameName/ ← everything about your game lives here
Docs/ ← One Sheet, Game Design Doc, level maps
PC_Builds/ ← Windows builds
WebGL_Builds/ ← browser builds for itch.io
Put it somewhere that is not a synced cloud folder — OneDrive and Dropbox corrupt Unity Library folders.
This structure matters all semester. Your builds and your documents live beside the Unity project, never inside it. A build placed inside Assets/ gets imported by Unity, which is slow, messy, and occasionally breaks the project.
2. Create the Unity project
Unity Hub → New Project → Universal 2D template.
Name it MyGameName_Unity and set the location to your MyGameName/ folder.
You should now have:
MyGameName/
MyGameName_Unity/ ← Unity made this
Assets/
Library/ ← never touch, never back up
Packages/
ProjectSettings/
Docs/
PC_Builds/
WebGL_Builds/
3. Make your Assets folders
Inside Assets/, create exactly this:
Assets/
Art/
Audio/
Input/
Prefabs/
Scenes/
Scripts/
UI/
Everything you make goes in one of these. Imported packages will add their own folders alongside — that's fine, leave them alone. In Week 13, when your project has 400 files, this is the only reason you'll be able to find anything.
4. Import the helpers
Assets → Import Package → Custom Package → HelperScripts.unitypackage → Import all.
5. Save your scene
Assets/Scenes/Sandbox.unity. Save it now, and press Ctrl+S every time you look up from the screen for the rest of the semester.
✅ Checkpoint 1 — folders exist, helpers imported, scene saved with a name.
Part 2 — The sprite (10 min)
6. Import your sprite
Drag your PNG into Assets/Art/.
7. Set the import settings
Select the sprite. In the Inspector:
| Setting | Value |
|---|---|
| Texture Type | Sprite (2D and UI) |
| Pixels Per Unit | 32 |
| Filter Mode | Point (no filter) for pixel art · Bilinear for smooth art |
| Compression | None |
Click Apply.
Pixels Per Unit is the most important number in your project. It defines how many pixels equal one Unity unit — one world "meter." Every speed, jump height, and distance you tune from now on is expressed in those units. Write down what you chose. Do not change it later, or every value in your game silently becomes wrong.
If your character art is 32 px tall and PPU is 32, your character is 1 unit tall. That's a good default.
8. Put it in the scene
Drag the sprite from the Project window into the Hierarchy. Rename it Player. Set its Transform position to 0, 0, 0.
✅ Checkpoint 2 — a sprite is visible in Game view, one unit tall, positioned at origin.
Part 3 — The Input System (20 min)
9. Install the package
Window → Package Manager → Unity Registry → search Input System → Install.
When it asks about enabling the new backends and restarting, click Yes. The editor restarts. This is normal.
We use the new Input System all semester. Do not use
Input.GetAxisorInput.GetKey— they belong to the old system, they will not work with these settings, and they are not accepted in this course.
10. Create the Input Actions asset
Right-click Assets/Input/ → Create → Input Actions. Name it PlayerControls.
Double-click it to open the editor, and click Edit asset if prompted.
11. Build the action map
Click + under Action Maps → name it Gameplay.
Now add two actions. The names must match exactly — the helper script listens for them by name.
Action: Move
- Action Type: Value
- Control Type: Vector 2
- Add a binding → Add Up/Down/Left/Right Composite, name it
WASD:- Up →
W [Keyboard] - Down →
S [Keyboard] - Left →
A [Keyboard] - Right →
D [Keyboard]
- Up →
- Add a second binding →
Left Stick [Gamepad]
Action: Jump
- Action Type: Button
- Binding →
Space [Keyboard] - Second binding →
Button South [Gamepad]
Click Save Asset. Nothing saves automatically in this window, and this is the single most common thing to forget.
✅ Checkpoint 3 —
PlayerControlshas aGameplaymap withMoveandJump, each bound to keyboard and gamepad, and it's saved.
Part 4 — Movement (20 min)
12. Add the components
Select Player and Add Component for each:
| Component | Settings |
|---|---|
| Rigidbody2D | Gravity Scale 0 for top-down, 3 for side-scrolling · Freeze Rotation Z ✔ |
| Box Collider 2D | Should wrap your sprite — adjust size if it doesn't |
| Player Input | Actions: PlayerControls · Default Map: Gameplay · Behavior: Send Messages |
| PlayerMove2D | The helper script |
Behavior must be Send Messages. PlayerMove2D implements OnMove and OnJump, which the Input System calls automatically when the behavior is set this way. Any other behavior and nothing happens.
13. Press Play
Your sprite should move. If it doesn't, jump to Troubleshooting below.
14. Tune it — this is the graded part
Open PlayerMove2D in the Inspector and change these while in Play mode:
| Value | What it does | Try |
|---|---|---|
moveSpeed | Top speed in units/second | 3, then 8, then 15 |
acceleration | How fast you reach top speed | 5, then 50 |
deceleration | How fast you stop | 5, then 50 |
jumpHeight | Peak height in units | 1, then 4 |
Play with each one at both extremes before settling. Notice that acceleration changes the feel far more than speed does — high speed with low acceleration feels like ice, low speed with high acceleration feels responsive and heavy.
⚠️ Values changed during Play mode reset when you stop. Once you find numbers you like, write them down, stop, and re-enter them.
15. Write down your decision
In your MyGameName/Docs/ folder, make a text file Ex01_notes.txt with:
Pixels Per Unit: 32
moveSpeed: 6.5
acceleration: 25
deceleration: 30
jumpHeight: 3.2
Why: I wanted it to feel responsive but weighty, like Celeste rather
than Mario. Speed 8 overshot my platforms, so I dropped to 6.5 and
raised acceleration to 25 so it reaches top speed almost instantly
without actually being fast.
Three sentences minimum, naming a specific reference or intention. This paragraph is one of your two points. "I made it feel good" earns nothing; the example above earns full marks.
✅ Checkpoint 4 — movement works on keyboard and gamepad, values are deliberately set, notes written.
Part 5 — Build and submit (10 min)
16. Build it
File → Build Profiles → Windows → Build.
Build into MyGameName/PC_Builds/Ex01/.
This is why PC_Builds/ sits beside the Unity project rather than inside it — Unity never imports it, and you can zip it without dragging the whole project along.
Building today, in Week 1, on a project with one sprite in it, is deliberate. The first build always surprises someone, and it's much better that it happens now than in Week 15.
17. Record it
15–30 seconds of screen capture showing the character moving. Use the Windows Game Bar (Win+G), OBS, or your phone pointed at the monitor. Quality is not graded.
18. Submit
Zip these three things as lastname_ex01.zip:
PC_Builds/Ex01/— the whole folder- Your recording
Docs/Ex01_notes.txt
Canvas → Assignments → Exercise 1. Due before you leave.
Rubric — 2 points
| Criterion | Pt | Met when |
|---|---|---|
| Implementation | 1 | Build runs · sprite moves on keyboard and gamepad · no console errors · PPU set and sprite import configured |
| Design decision | 1 | Tuning values deliberately changed from defaults, written down, with a stated intention or reference naming what you were going for |
Both are met-or-not-met. Late submissions earn the Implementation point only.
Troubleshooting
Nothing moves.
Check, in order: Player Input Behavior is Send Messages; Actions field points at PlayerControls; Default Map is Gameplay; the action is named exactly Move; you clicked Save Asset in the Input Actions window.
"InvalidOperationException: You are trying to read Input using the UnityEngine.Input class..."
Something is still using the old input system. Edit → Project Settings → Player → Active Input Handling → set to Input System Package (New) or Both.
The sprite falls forever.
Gravity Scale on the Rigidbody2D. Set it to 0 for top-down. For side-scrolling you need a floor — make an empty GameObject with a Box Collider 2D and stretch it under the player.
The sprite spins when it hits things.
Rigidbody2D → Constraints → Freeze Rotation Z.
Movement is jittery.
Rigidbody2D → Interpolate → Interpolate.
The sprite is blurry.
Filter Mode → Point (no filter), Compression → None, and Apply.
The sprite is enormous or microscopic.
Pixels Per Unit. Set it to match your art's pixel height for a one-unit-tall character.
If you finish early
- Bind a second control scheme and test the gamepad properly.
- Add a
dashSpeedanddashDurationinPlayerMove2Dand bind a Dash action. - Try PPU 16 and PPU 64 on the same sprite and observe what happens to every one of your tuned values. This is why you don't change it later.
- Open
PlayerMove2D.csand read it. You are not expected to write this, but you should be able to find the line that appliesmoveSpeed.
Before next week
Week 2 is your Game Pitch, live, three minutes. Bring a reference image and, if you're pitching a puzzle game, a paper prototype. See milestone-1-game-pitch.md.