Guide 5 — Last Delivery

Chris Acosta


What you're building

A food delivery robot crossing a wasteland from point A to point B. Monsters try to intercept you and steal the food. Top-down, Crossy Road–adjacent.

Yours is the second movement rig in the class — no gravity, no jumping. And it has one design decision baked in that's worth understanding before you build: the food is the resource, not your health.

Time: about two and a half hours.


1. Before you start


2. Scripts you'll use

Movement (Tier 5)
TopDownMover · (optionally GridMover, see section 3)

Delivery (Tier 5)
DeliveryObjective · DeliveryPoint · DroppedCargo · LaneSpawner

Combat (Tier 2)
Team · Hurtbox · Hitbox · EnemyChase · EnemyPatrol

Core
Health · DamageOnContact · Checkpoint · RespawnManager · CameraTargetAssigner · SceneLoader · GameManager · AudioManager · HUDController


3. The design decision: what does failure mean?

Your pitch says monsters "try to intercept you to steal the food." That's a different game from "monsters hurt you," and the kit supports the first one directly.

DeliveryObjective treats cargo as the resource. A monster hit makes you drop a package into the world, which you can scramble back to recover before it despawns. Arrive at the customer with nothing and the delivery fails.

Why this is the better fit for your game:

You can have both. Wire Health.OnDamaged → DeliveryObjective.LoseOne and monsters both hurt you and cost you food. I'd build cargo-only first and see whether it needs more.

Movement mode

This guide uses TopDownMover. If you want the grid feel, swap the component and read Guide 2 §3 for the settings.


4. Build the robot

  1. GameObject → Create Empty, name it Robot. Tag → Player.
  2. Sprite Renderer with your robot sprite.
  3. Add:
Component Settings
Rigidbody2D Gravity Scale 0 · Freeze Rotation Z ✓ · Collision Detection Continuous
Capsule Collider 2D fit the robot
Player Input Behavior: Send Messages · Default Map Player
TopDownMover see below
Health Max Health 3 · Invulnerability Time 1
DeliveryObjective section 5

TopDownMover settings

Field Value Note
Move Speed 5
Acceleration 50
Deceleration 60
Normalize Diagonal ✓ stops diagonal movement being 40% faster
Facing RotateSprite a robot that turns to face its direction reads well
Rotation Offset 0 set to −90 if your art points up instead of right
AI Controlled ✗

Facing modes: RotateSprite suits a vehicle or robot. FlipSprite is simplest if your robot is symmetrical. FourDirection needs eight animation clips — good, but a lot of art. Start with RotateSprite.

  1. Child Hurtbox: trigger collider, Hurtbox component (Team = Player), object layer Hurtbox.

  2. Child CarriedFood: a small sprite of the package, positioned above the robot. This is what shows you're carrying something — DeliveryObjective shows and hides it.


5. Set up the cargo system

On Robot, fill in DeliveryObjective:

Field Value
Starting Cargo 3
Carried Visual drag the CarriedFood child in
Dropped Cargo Prefab your DroppedFood prefab (build it next)
Drop Force 3
Loss Cooldown 1
Lose Sfx cargo_lost
Pickup Sfx collect
Deliver Sfx delivered

Loss Cooldown 1 means one monster can't strip you of everything in a single collision. It's the difference between a tense moment and an instant loss.

Starting Cargo 3 gives the player room to lose one and keep going. Set it to 1 if you want a single precious package and a much harder game — that's a legitimate design choice, just a harsher one.

The dropped food prefab

  1. Empty GameObject DroppedFood + Sprite Renderer.
  2. Rigidbody2D: Gravity Scale 0, Linear Damping 3 (so it slides and stops).
  3. Circle Collider 2D, Is Trigger ✓.
  4. DroppedCargo component:
Field Value
Despawn After 8
Blink Before Despawn 3
Pickup Delay 0.4
  1. Save as a prefab and drag it into DeliveryObjective's Dropped Cargo Prefab slot.

Despawn After 8 is your tension dial. Eight seconds is enough to turn around and grab it if you're quick. Drop it to 5 and recovery becomes a real risk.


6. Build the monsters

You want two kinds: predictable traffic and unpredictable hunters. The mix is what makes a route into a puzzle.

The hunter (chases you)

  1. Empty GameObject Monster, Tag → Enemy, sprite.
  2. Rigidbody2D (Gravity Scale 0, Freeze Rotation Z), Capsule Collider 2D.
  3. Health — Max Health 3 · Destroy On Death ✓ (they can't actually be killed in your game, but it prevents oddities)
  4. EnemyChase:
Field Value
Detect Radius 6
Lose Radius 10
Require Line Of Sight ✗ (no walls in an open wasteland)
Movement Free — no gravity, moves in all directions
Chase Speed 3.5 — slower than you, so you can outrun them
Acceleration 10
Attack Range 0.8
Attack Cooldown 2
Stop In Range ✗
  1. Child Hurtbox: Team = Enemy, layer Hurtbox.
  2. Child StealHitbox: trigger collider + Hitbox:
Field Value
Target Team Player
Damage 0 ← important
Knockback Force 4
Repeat Delay 1.5

Damage 0 is the trick. The monster hits you, knocks you back, but doesn't hurt your health — it steals food instead. Wire that in section 9.

  1. Save as a prefab.

Chase Speed must be lower than your Move Speed. At 3.5 against your 5, a monster is a threat you can escape by running — which makes running a real option, and running while carrying something is your game.

The lane traffic

  1. Make a hazard prefab — a rolling barrel, a mutant, a wrecked truck. Sprite + Rigidbody2D (Gravity 0) + trigger collider + DamageOnContact (Target Tag Player, Damage 1, or Damage 0 if you want it to steal too).
  2. Empty GameObject Lane1 at one edge of the play area.
  3. Add LaneSpawner:
Field Value
Direction (1, 0) for left-to-right
Lane Length 24 (wide enough to cross the whole screen)
Prefabs your hazard prefab
Max Alive 4
Start Delay 0
Interval 2
Interval Variance 0.5
Speed 4
Speed Variance 1
Face Direction ✓
Rotate Instead Of Flip ✓ for vehicles, ✗ for creatures
  1. Duplicate for more lanes. Stagger the Start Delay (0, 0.7, 1.4) so they don't all fire in sync — a wall of simultaneous hazards is unfair, a rhythm is a puzzle.

The orange gizmo arrow in the Scene view shows where a lane sends things. Use it.


7. Point B — the delivery point

  1. Empty GameObject CustomerDoor at the end of your route, + sprite (a house, a hungry customer).
  2. Box Collider 2D, Is Trigger ✓.
  3. DeliveryPoint:
Field Value
Required Cargo 1
Complete Level ✓
Set Flag On Delivery (leave empty)

Required Cargo 1 means arriving with anything at all counts as a success. Set it to 3 and you must arrive with everything — much harder, and it makes every dropped package a genuine crisis. Start at 1.


8. Camera, managers, HUD

Camera

Guide B §B3, with one change: for a top-down game set Damping X and Y both to 0.8 — even damping, since there's no "up" that matters more.

If your route is a long corridor, add the CinemachineConfiner2D and a bounds polygon.

Managers

GameManager, RespawnManager, AudioManager, SceneLoader. On RespawnManager, Use Lives ✗ — your fail state is losing the food, not running out of lives.

HUD

  1. Canvas → TMP text CargoText, top-left. Text: Packages: 3.
  2. Optionally a health bar or hearts.
  3. Empty child HUD with HUDController; drag your health display in.

The cargo count needs its own wiring since it doesn't come from CollectionTracker — see the next section.


9. Wire it up

On this object Event Drag in Choose
Monster → StealHitbox Hitbox On Hit Robot DeliveryObjective.LoseOne
Robot → DeliveryObjective On Cargo Changed CargoText TMP_Text.text — see note
Robot → DeliveryObjective On All Cargo Lost GameManager GameManager.GameOver
Robot → DeliveryObjective On Cargo Lost AudioManager PlaySFX (string) → cargo_lost
CustomerDoor → DeliveryPoint On Arrived Empty GameManager GameManager.GameOver
Robot → Health On Died RespawnManager RespawnManager.OnPlayerDied
Robot → Health On Health Changed HUD HUDController.UpdateHealth (Dynamic)

Row 1 is the heart of your game. The monster's hitbox fires OnHit, which calls LoseOne on the robot. That's the theft.

Row 2 note: OnCargoChanged sends an int and TMP's text wants a string, so they don't connect directly. Two easy options:

Ask your instructor if you'd rather have the number — it's a two-line helper script.


10. First playtest

Build a short open area with one hunter, one lane, and the customer door twenty units away.

  1. The robot moves in 8 directions and doesn't fall (Gravity Scale 0).
  2. Diagonals aren't faster — Normalize Diagonal ✓.
  3. The carried food shows above the robot, and vanishes when cargo hits 0.
  4. A monster notices you and chases, but you can outrun it.
  5. A monster hit drops a package into the world — you should see it appear and slide.
  6. You can pick the dropped package back up after a moment.
  7. The dropped package blinks and vanishes after 8 seconds.
  8. Losing all packages ends the game.
  9. Reaching the door with at least one package completes the level.
  10. Arriving empty fails rather than succeeding.

Step 5 is the one to check carefully — it's your whole design. If a monster hit does nothing, the OnHit → LoseOne wiring is missing or the hitbox teams are wrong.


11. Then add

  1. The route. Your systems are done; the game is the layout. Wide open stretches to run, pinch points where lanes force timing, safe pockets to breathe.
  2. More monster types — one faster than you but with a short detect radius, one slow with a huge radius.
  3. Checkpoints if your route gets long.
  4. EnemyPatrol monsters that walk fixed routes — predictable danger you can plan around.
  5. A second delivery in the same level: two DeliveryPoints, deliver to both.
  6. Sound: an alarm when a monster notices you, a clatter when food drops, a chime on delivery.

12. Design notes for your game specifically

Predictable plus unpredictable is the recipe. Lane traffic you can time, hunters you have to react to. Either alone gets boring — traffic becomes a rhythm you memorise, hunters become a chase you just outrun. Together, the traffic constrains where you can dodge to, and that's the interesting problem.

The dropped package is the best thing in your design. It turns a hit from a punishment into a decision under time pressure: the food is on the ground, a monster is closing, and you have eight seconds. Tune Despawn After until that choice is genuinely hard.

Make the monsters slower than you. A monster you can't outrun isn't a threat, it's a timer. At 3.5 against your 5, escape is always possible but never free — especially when the escape route runs through traffic.

The wasteland is a character. Crossy Road works partly because the world is legible at a glance — you can see every lane and every gap. Keep your layout readable from the camera's view; a route the player can plan is more fun than one they discover by dying.


13. Common problems

What you see What's wrong
Robot falls off the screen Gravity Scale isn't 0
Diagonal movement is faster Normalize Diagonal unticked
Robot spins constantly Freeze Rotation Z unticked, or Facing is RotateSprite with the wrong Rotation Offset
Monster hit does nothing OnHit → LoseOne not wired, or hitbox/hurtbox teams are the same, or layers wrong
Monster hit hurts health instead of stealing Hitbox Damage isn't 0
One monster takes all your cargo at once Loss Cooldown is 0 — set it to 1
Dropped food can't be picked up Pickup Delay too long, or it's not on a trigger collider
Dropped food never disappears Despawn After is 0
Lane hazards don't appear Prefabs list empty, or Max Alive is 0
All lanes fire at once Give each a different Start Delay
Hazards fly off in the wrong direction Check the Direction vector and the gizmo arrow
Delivery point does nothing Not a trigger, or the robot isn't tagged Player, or Required Cargo is higher than what you have

14. Checklist