Guide 12 — Roach Invasion
Joshua Freeman
What you're building
A 2D collectathon platformer. You switch between four insects with different abilities and health, evading mutated cockroaches and collecting all the plant-based items — picking whichever bug suits each enemy and hazard.
Your build has one thing nobody else's does: four playable characters with separate health pools. When one insect runs out, you switch to another; when they're all down, you respawn. That changes how death is wired, so read section 3 carefully.
Your sketch has HP written on each bug — 5, 3, 2, 3. Those go straight into the character assets.
Time: about three hours.
1. Before you start
- Finish Guide 0.
- Read Guide B §B1 (player) and §B4 (enemies).
- No new input actions — swapping uses the built-in
Previous/Next(Q and E).
2. Scripts you'll use
Core — Guide B
PlayerController2D · PlayerAnimatorBridge · Health · DamageOnContact · Checkpoint · RespawnManager · CameraTargetAssigner · SceneLoader · GameManager · AudioManager · HUDController · MovingPlatform · ParallaxBackground
Collectibles
ItemType · Collectible · CollectionTracker
Enemies (Tier 2)
EnemyPatrol · EnemyChase · FloatingEnemy · Hurtbox · Hitbox · Knockback
Movement (Tier 3)
DoubleJump · Glide · Ladder + LadderClimber · CharacterDefinition · CharacterSwapper
Level (Tier 4)
SpikeTrap · KillZone · Door · LevelExit
3. How character swapping actually works
Read this before building anything — it's not what most people expect.
You do not make four player prefabs. You make one player object that carries every ability component, and a CharacterDefinition asset per insect that says which abilities are switched on, what the stats are, and which animator to use.
Why: four separate prefabs would each need their own camera target, PlayerInput, respawn wiring and hurtbox. Swapping between them means re-pointing all of that every time. One object with toggled components avoids all of it.
The death wiring is different for you
Every other guide wires Health.OnDied → RespawnManager.OnPlayerDied. You don't.
Health.OnDied → CharacterSwapper.OnCurrentCharacterDied
RespawnManager.OnRespawned → CharacterSwapper.ReviveAll
When an insect's health hits zero, CharacterSwapper marks that one down and switches to a living one. Only when all four are down does it call RespawnManager itself. Wire it the normal way and you'll respawn on the first insect's death, which throws away your entire mechanic.
4. Build the one player object
Follow Guide B §B1, but with every ability component attached. Most will be disabled at any moment — that's correct.
- Empty GameObject
Player, Tag →Player, Sprite Renderer. - Rigidbody2D (Gravity Scale 3, Freeze Rotation Z, Continuous), Capsule Collider 2D.
- Player Input — Behavior: Send Messages.
PlayerController2D+GroundCheckchild + Ground Layer.Health— the values get overwritten per character, but set Invulnerability 1.Animator+PlayerAnimatorBridge.Knockback.- All the ability components, in any order:
DoubleJumpGlideLadderClimber- (add
Dashtoo if you want one insect to have it)
CharacterSwapper— configure in section 6.- Child
Hurtbox— trigger collider, Hurtbox (Team = Player), layerHurtbox.
After step 8 the Inspector will look crowded and several components will be greyed out during play. That's the design working.
5. Create the four insects
Right-click in Project → Create → GAME1303 → Character, four times.
The Enabled Abilities list holds component type names as text — spelling and capitals must match exactly.
Beetle (the tank — 5 HP)
| Field | Value |
|---|---|
| Display Name | Beetle |
| Max Health | 5 |
| Move Speed | 6 (slow) |
| Jump Force | 12 |
| Gravity Scale | 3.5 (heavy) |
| Enabled Abilities | LadderClimber |
| Animator Controller | your beetle controller |
| Tint | white |
Mantis (the climber — 3 HP)
| Field | Value |
|---|---|
| Max Health | 3 |
| Move Speed | 8 |
| Jump Force | 14 |
| Gravity Scale | 3 |
| Enabled Abilities | DoubleJump, LadderClimber |
Bee (the flier — 2 HP)
| Field | Value |
|---|---|
| Max Health | 2 |
| Move Speed | 9 |
| Jump Force | 13 |
| Gravity Scale | 1.5 (light) |
| Enabled Abilities | Glide, DoubleJump |
Ant (the all-rounder — 3 HP)
| Field | Value |
|---|---|
| Max Health | 3 |
| Move Speed | 8 |
| Jump Force | 14 |
| Gravity Scale | 3 |
| Enabled Abilities | LadderClimber |
The animator trap
If you make four Animator Controllers, they must all use the same parameter names (Speed, IsGrounded, YVelocity, Jump). CharacterSwapper swaps the whole controller, and parameter values only carry across if the names match. A typo means the animation silently resets on every swap.
Simplest safe route: build one controller, then duplicate it three times and only change the clips. The parameters come along for free.
6. Configure the swapper
On Player, fill in CharacterSwapper:
| Field | Value |
|---|---|
| Characters | drag all four assets in, in the order you want Q/E to cycle |
| Start Index | 0 |
| Swap Cooldown | 0.3 |
| Separate Health Per Character | ✓ ticked |
| Allow Swap In Air | ✓ |
| Ability Components | (leave empty — it fills itself from the object) |
Separate Health Per Character ✓ is your mechanic. Each insect keeps its own health, and a dead one can't be selected until you respawn.
Optional: add Character1–Character4 button actions to your input asset (bound to keys 1–4) if you want direct selection alongside Q/E cycling. The swapper listens for them automatically if they exist.
7. Build the level
The collectibles
- Right-click Project → Create → GAME1303 → Item Type, name it
Plant. Score Value 10. PlantPickupprefab: sprite + trigger Circle Collider 2D + Collectible (Item Type →Plant, Bob ✓).- Place them everywhere — that's your game.
CollectionTrackerin the scene.
The roaches
Your pitch says mutated cockroaches, and your sketch shows a "stinky" one.
Ground roach — Guide B §B4 with EnemyPatrol (Sensors mode), Health 2, Hurtbox (Team Enemy), BodyHitbox (Damage 1, Repeat Delay 1).
Flying roach — Rigidbody2D Gravity Scale 0, FloatingEnemy (Path Wander, Wander Radius 4, Bob Height 0.3), plus EnemyChase (Movement Free, Detect 6, Speed 3). Hurtbox and BodyHitbox as above.
Stinky roach — a ground roach with a big trigger child that has DamageOnContact (Damage 1, Repeat Interval 1). The cloud is the threat, not the body — that's a hazard your bee can fly over and your beetle can't.
Level furniture
- Ground on
Groundwith colliders KillZoneunderneathSpikeTraps (Guide 1 §6e recipe) — Damage 1, not Instant KillLadders: a sprite + trigger Box Collider 2D covering the full climb + theLaddercomponentCheckpoints- A
Doorrequiring all plants, in front of the exit LevelExitbeyond it- Camera per Guide B §B3
Gate the exit on collecting everything
On the Door:
| Field | Value |
|---|---|
| Requirement | Collect |
| Required Item | Plant |
| Required Count | (however many you placed) |
| Consume On Open | ✗ |
| Open Mode | Slide |
Add a trigger child and drag it into Proximity Zone so it checks as you approach. Wire OnOpenFailed to a sound so a short player gets told, not just blocked.
8. The HUD
You need more here than most guides, because the player has to see four health pools.
- Canvas →
PortraitImage(Image) showing the current insect. NameText(TMP) showing its name.- A health bar Slider or hearts.
PlantText(TMP) —Plants: 0 / 20.- Empty child
HUDwith HUDController:- assign the health bar or hearts
- Item Counters → one entry: Item Type
Plant, TextPlantText, FormatPlants: {0}
Showing which insects are still alive
The nicest version is four small portraits in a row, greyed out as each falls. That needs a short script — worth asking for, since it's the readout your mechanic depends on. A simpler stand-in: OnCharacterChanged swaps the single portrait, and the health bar shows only the current insect. That works, it just hides how much reserve you have left.
9. Wire it up
| On this object | Event | Drag in | Choose |
|---|---|---|---|
Player → Health | On Died | Player | CharacterSwapper.OnCurrentCharacterDied |
RespawnManager | On Respawned | Player | CharacterSwapper.ReviveAll |
Player → Health | On Health Changed | HUD | HUDController.UpdateHealth (Dynamic) |
CollectionTracker | On Count Changed | HUD | HUDController.UpdateItemCount (Dynamic) |
Player → CharacterSwapper | On Character Changed | AudioManager | PlaySFX (string) → swap |
Door | On Open Failed | AudioManager | PlaySFX (string) → door_locked |
Player → PlayerController2D | On Jumped | AudioManager | PlaySFX (string) → jump |
Rows 1 and 2 are the ones to double-check. Row 1 must go to CharacterSwapper, not RespawnManager — that's the difference between your game and a normal platformer.
10. First playtest
Build a small room with a ladder, a gap the bee can glide over, and two roaches.
- You start as the Beetle with 5 health.
- Q and E cycle through the four insects.
- Each insect has different stats — the bee should visibly float more (Gravity Scale 1.5).
- The bee can glide (hold Jump while falling) and the beetle can't.
- The mantis and bee can double jump; the beetle and ant can't.
- Every insect can climb the ladder except any you left
LadderClimberoff. - Damage only hurts the current insect — take a hit as the Ant, swap to the Beetle, confirm the Beetle still has 5.
- When an insect hits 0, you auto-swap to a living one rather than dying.
- A dead insect can't be selected — cycling skips it.
- When all four are down, you respawn at the checkpoint with everyone revived.
Steps 7–10 are the whole build. Test them deliberately: drop three insects on purpose and confirm the fourth is still playable, then drop the fourth and confirm you respawn.
11. Then add
- Level design that needs the swap. Right now the insects are different; make them necessary. See the design notes.
- Animation — four controllers, identical parameters. Guide B §B6.
- A
Dashinsect if you want a fifth ability — addDashto the player and list it on one character. ParallaxBackground— grass and stems in layers.- A second level with a different plant count.
- Sound: a distinct swap sound, per-insect footsteps if you're ambitious.
12. Design notes for your game specifically
Right now you have four insects. Make them four keys. The mechanic only sings when the level asks for a specific bug:
- A gap only the bee can cross (glide)
- A crushing hazard only the beetle survives (5 HP)
- A high ledge needing the mantis (double jump)
- A narrow tunnel where the tanky beetle is too slow to escape a chasing roach
One of each of those makes the swap essential. Without them, players find a favourite and never switch — and your whole design becomes a character-select screen.
Separate health is a resource, not four lives. The interesting decision isn't "which bug do I like," it's "the bee is on 1 HP and there's a flying section coming — do I use her now or save her?" Make sure there's at least one section per level where a specific insect is needed, so spending them carelessly has a cost.
2 HP on the bee is right. She has the most useful ability and the least durability. That's the trade that makes gliding feel like a decision instead of a free upgrade. Don't be tempted to buff her.
Collectathon means the level is the content. Your systems will be done after section 8. Everything after that is placing plants in interesting places — behind a glide, above a double jump, past a hazard only the beetle survives. Every plant should be a small question about which bug to use.
Watch out for softlocks. If a plant is behind a bee-only glide and the bee is dead, the player is stuck until they respawn. That's usually fine — respawning revives everyone — but make sure a checkpoint is reachable from anywhere. Test this specifically.
13. Common problems
| What you see | What's wrong |
|---|---|
| Respawn on the first insect's death | Row 1 wired to RespawnManager instead of CharacterSwapper |
| Dead insects come back immediately | RespawnManager.OnRespawned → ReviveAll missing, or Separate Health unticked |
| All insects share one health pool | Separate Health Per Character unticked |
| Q/E do nothing | Previous/Next missing from the input asset, or Characters list empty |
| An ability doesn't work for any character | Component missing from the player object entirely |
| An ability works for the wrong character | Typo in Enabled Abilities — it must match the class name exactly, e.g. DoubleJump not Double Jump |
| Every character has every ability | Ability Components list was filled manually and wrongly — clear it and let it auto-fill |
| Animation resets on every swap | The four Animator Controllers use different parameter names |
| Stats don't change between insects | Characters list has the same asset four times |
| Swapping spams | Swap Cooldown is 0 |
| Door won't open with all plants | Required Count doesn't match how many you placed — count them |