Minimal Space Invaders (Unity / C#)

The step-4 project in overview-arcade-classics-as-learning-projects. It is the first project in the route with multiple interacting systems, and it introduces the four skills the canon reference (see source-classic-games-canon) lists for Space Invaders: enemy formations, timers, projectile pooling, and state changes (plus lives).

Original project inspired by a recognisable pattern — not a clone.

Files

ScriptResponsibilityKey wiki concept
IHittable.csOne-method interface so a bullet can damage anythingcsharp-interfaces
ProjectilePool.csReuses bullets instead of Instantiate/Destroy per shotobject-pool-pattern
Projectile.csPooled, transform-driven bullet; hits a target layer, returns itselfunity-collider2d-and-triggers
PlayerShip.csMove + fire on a cooldown timer; takes a hitunity-input
Invader.csOne formation member; dies on hit, reports to the formationcsharp-interfaces
InvaderFormation.csMarches the grid, edge-drops, fires on a timer, speeds up per killcsharp-collections
SpaceInvadersGame.csOwns score, lives, and the State machine; wave/lose flowunity-gamemanager-pattern, csharp-enums

What is new at this step

  • Enemy formation. Every invader is a child of InvaderFormation, so the whole grid marches by moving one transform. The formation reverses and drops a row when its edge reaches the screen, and it tracks survivors in a List.
  • Timers. Two independent timers drive the game: one steps the march, one fires from a random survivor. The player’s fire rate is a third cooldown timer. All are frame-rate independent (accumulating Time.deltaTime).
  • Projectile pooling. Both sides share one ProjectilePool, firing the same prefab parameterised by direction and target layer. This is the route’s first real use of object-pool-pattern.
  • State changes. SpaceInvadersGame holds a State enum and routes every event (invader killed, wave cleared, player hit, invaders landed) through it.

Scene setup (about 15 minutes)

  1. New 2D scene, Main Camera set to Orthographic.
  2. Add two user layers: Player and Invaders (Edit → Project Settings → Tags and Layers).
  3. Bullet prefab: a small thin square sprite, add a Box Collider 2D and the Projectile script. Make it a prefab; delete the scene copy. (It needs no layer of its own — it targets a layer.)
  4. Pool: empty GameObject BulletPool, add ProjectilePool, assign the bullet prefab.
  5. Player: a square sprite near the bottom, layer Player, with a Box Collider 2D and the PlayerShip script. Assign Bullet Pool, and set Invader Mask to the Invaders layer.
  6. Invader prefab: a square sprite, layer Invaders, with a Box Collider 2D and the Invader script. Make it a prefab; delete the scene copy.
  7. Formation: empty GameObject Formation, add InvaderFormation, assign the invader prefab and the Bullet Pool, and set Player Mask to the Player layer.
  8. Game: empty GameObject Game, add SpaceInvadersGame, and drag in the Player and Formation.
  9. Press Play. Move with A/D or arrows, Space to fire. Clearing the wave starts a faster one; losing all lives restarts. Score, lives, and waves print to the Console.

Why pooling here

A wave can put dozens of bullets on screen per second. Instantiating and destroying each one churns memory and can cause GC hitches — exactly the case object-pool-pattern is built for. Swapping the pool for plain Instantiate/Destroy and watching the unity-profiler is a good exercise.

Extension ladder

These lead toward step 5 (Asteroids, vector movement and wrapping):

  1. On-screen score, lives, and wave — replace Debug.Log with UI/TMP text.
  2. Destructible shields — bunkers that erode from both bullet directions (reuses Breakout’s brick idea).
  3. Animation frames — alternate the invader sprite each march step for the classic shuffle; first touch of unity-animator-scripting.
  4. Dive attacks — occasionally peel an invader out of formation to swoop (the bridge to Galaga and to steering-behaviours).
  5. Audio and hit feedback — the rising march tempo is iconic game-feel; see unity-audiosource.

Source files

7 items under this folder.