Guide 8 — Stardust

Marcelo Diaz


What you're building

A 2D action platformer where you dash, jump and attack through levels. The core mechanic is comboing — the more consecutive hits you land, the more damage you do.

Yours is the most complete action-game build in the class: melee, projectiles, dash, wall-sliding, a combo system and a boss. If another student wants to see everything the combat kit can do, they should read your guide.

Your title is a placeholder, which is fine — nothing here depends on the name.

Time: about three hours.


1. Before you start


2. Scripts you'll use

Core — Guide B §B1, §B2
PlayerController2D · PlayerAnimatorBridge · Health · DamageOnContact · Checkpoint · RespawnManager · CameraTargetAssigner · SceneLoader · GameManager · AudioManager · HUDController · MovingPlatform · ParallaxBackground

Combat (Tier 2)
Team · Hurtbox · Hitbox · Knockback · ComboCounter · MeleeAttack · Projectile · ProjectileShooter · EnemyPatrol · BossController · BossArenaTrigger

Movement (Tier 3)
Dash · WallSlideJump

Level (Tier 4)
SpikeTrap · Breakable · KillZone


3. How the combo system works

Worth understanding before you build, because it touches three components.

ComboCounter sits on the player. Every time one of your attacks lands, the counter goes up. Your damage multiplier is:

multiplier = 1 + (combo × Damage Per Hit), capped at Max Multiplier

At the default 0.1 per hit, ten consecutive hits means double damage. The combo resets if you go 2 seconds without landing a hit, or if you take damage.

The important part: Hitbox reads the multiplier automatically from the ComboCounter on its parent. You don't wire that. What you do wire is RegisterHit, so the counter knows a hit landed.

Projectiles are different. A projectile fired by a ProjectileShooter on the same object as the ComboCounter registers its own hits automatically. Don't wire those or they'll count twice.


4. Build the player

Follow Guide B §B1, then set:

Component Setting Value
Health Max Health 5
Invulnerability Time 0.8
PlayerController2D Move Speed 9
Acceleration 70 — snappy
Deceleration 90
Jump Force 15
Coyote Time 0.1
Jump Buffer Time 0.12

Add Knockback (Stun Duration 0.2, Resistance 0) and ComboCounter:

Field Value
Combo Window 2 — seconds between hits before it drops
Damage Per Hit 0.1
Max Multiplier 3

The children

Hurtbox — trigger collider smaller than the sprite, Hurtbox (Team = Player), layer Hurtbox.

AttackHitbox — trigger collider in front, Hitbox:

Field Value
Target Team Enemy
Damage 1
Knockback Force 6
Knockback Upward 2

Layer Hitbox, GameObject unticked (starts disabled).

WallCheck — an empty child at chest height on the right side of the sprite. One is enough; it flips with the player.

GroundCheck — at the feet, per Guide B.


5. Add the movement modules

First: the Dash input action

Open your input actions asset:

  1. Player map → + → name it exactly Dash
  2. Action Type Button
  3. Add Binding → Path → Listen → press Left Shift
  4. Save Asset

MeleeAttack

On Player:

Field Value
Player Controlled ✓
Hitbox drag AttackHitbox
Windup 0.06
Active 0.1
Recovery 0.14
Use Animation Events ✗
Stop While Attacking ✓
Animator Trigger Attack
Sfx Name swing

Total: 0.3 seconds. That's fast, which is what a combo game needs — a slow attack makes chaining hits impossible. When you animate, match the clip to 0.3 or adjust these.

Dash

Field Value
Dash Speed 22
Dash Duration 0.15
Cooldown 0.5
Direction Facing (EightWay if you want Celeste-style)
Air Dashes 1
Invulnerable During Dash ✓
Keep Velocity After 0
Use Sprint Action ✗
Animator Trigger Dash
Sfx Name dash

WallSlideJump

Field Value
Wall Check drag the WallCheck child
Check Distance 0.2
Wall Layer Ground
Slide Speed 2
Require Pushing Into Wall ✓
Wall Jump Force (10, 14)
Lock Time 0.15
Refill Jumps ✓

6. Build enemies

Basic enemy

Guide B §B4, with:

Setting Value
Health Max 3 · Destroy On Death ✓ · Invulnerability 0
Knockback Resistance 0
EnemyPatrol Speed 2, Sensors mode, Ground Layer Ground

Children: WallCheck, LedgeCheck, Hurtbox (Team Enemy), BodyHitbox (Target Player, Damage 1, Repeat Delay 1, enabled).

Invulnerability 0 on enemies is important for you

Your game is about chaining hits. If enemies have i-frames, your combo stalls while you wait for them to become hittable again. Set it to 0 and let the attack's own cooldown pace the fight.

A tougher enemy

Duplicate, raise Health to 6, lower Speed to 1.5, change the sprite. Variety in how long something takes to kill is what makes a combo meter meaningful — a 6-health enemy is where your multiplier starts paying off.


7. Optional: give the player a projectile

If you want a ranged attack (your Mega Man ZX reference suggests you might):

  1. Bullet prefab: Sprite + Rigidbody2D (Gravity Scale 0) + Circle Collider 2D (trigger) + Projectile:
Field Value
Damage 1
Speed 14
Lifetime 2
Pierce 0
Blocking Layers Ground
  1. FirePoint empty child on the player, in front.
  2. ProjectileShooter on the player root:
Field Value
Projectile Prefab your bullet
Fire Point the child
Team Player
Mode Manual ← see warning
Aim Facing
Fire Rate 0.25

⚠️ MeleeAttack and ProjectileShooter both listen to the Attack action. If you set the shooter to PlayerInput mode, you'll melee and shoot on every press. Set it to Manual and add a separate Shoot action, or just skip the projectile — melee alone is a complete game.

If you want both: add a Shoot action to your input asset, then ask your instructor for the two-line script that calls Fire() from it. It's genuinely two lines.


8. Build the level

Design your level around the moves

You have dash, double-height wall jumps, and a fast attack. A level of flat corridors wastes all three. Build:


9. The HUD

  1. Canvas → a Slider named HealthBar (delete the handle, Interactable ✗, Min 0 Max 5).
  2. A TMP text ComboText, centre-right, initially empty.
  3. Empty child HUD with HUDController; drag HealthBar into Health Bar.

Making the combo readable

The combo counter is your whole identity as a game, so it needs to be felt. Cheap upgrades in order of value:

  1. Show the number and multiplier: 12 HITS ×2.2
  2. Scale the text up as the combo climbs
  3. Change colour at thresholds — white → yellow → orange → red
  4. Shake or flash it when it breaks

You can do 1 with wiring alone. The rest need a small helper script — worth asking for once the game plays well.


10. Wire it up

On this object Event Drag in Choose
Player → Health On Died RespawnManager RespawnManager.OnPlayerDied
Player → Health On Health Changed HUD HUDController.UpdateHealth (Dynamic)
AttackHitbox → Hitbox On Hit Player ComboCounter.RegisterHit
Player → Health On Damaged Player ComboCounter.ResetCombo
Player → ComboCounter On Combo Broken AudioManager PlaySFX (string) → combo_break
Player → Dash On Dash Started AudioManager PlaySFX (string) → dash
Player → PlayerController2D On Jumped AudioManager PlaySFX (string) → jump
Boss → BossController On Boss Defeated GameManager GameManager.LevelComplete

Rows 3 and 4 are your game. Without row 3 the combo never counts. Without row 4 it never resets, so it climbs forever and the multiplier becomes meaningless.

For row 3, note the event is on the child AttackHitbox, and you drag the parent Player into the slot. That trips people up.


11. First playtest

Build a room with three basic enemies and a wall.

  1. Run, jump, attack.
  2. Three hits kill a basic enemy.
  3. Dash works and has a cooldown. Left Shift.
  4. Air dash works once, then not again until you land.
  5. You're invulnerable mid-dash — dash through an enemy and take no damage.
  6. Wall slide: jump at a wall while holding toward it. You should slow down.
  7. Wall jump: press Jump while sliding. You should launch away and flip.
  8. Hit three enemies in a row and the combo climbs. Add a temporary TMP text wired to OnComboChanged if you need to see it.
  9. Stop hitting for 2 seconds — the combo resets.
  10. Take a hit — the combo resets.
  11. A 10-hit combo does noticeably more damage — test on the 6-health enemy.

Steps 8–11 are the whole point. Get them working before you build any level.


12. Then add

  1. Level design built around dash and wall-jump.
  2. Animation — Guide B §B6, plus Attack, Dash, IsWallSliding. Yours needs the most animator work of the first eight guides.
  3. A boss — Guide 7 §9 has the full recipe; give him Resistance 1 and two phases.
  4. Combo UI polish — the scaling, colouring text.
  5. Hit-stop: a two-frame freeze on impact makes hits feel heavy. Ask about it once combat is working; it's a small script and it's the single biggest "game feel" upgrade available to you.
  6. Sound: distinct hit sounds per combo tier, if you want to get fancy.

13. Design notes for your game specifically

Your combo window is a difficulty dial. Two seconds is generous — the player can reposition between hits. Drop it to 1.2 and they have to keep pressure on constantly, which makes the game much more aggressive. Try both; the right answer depends on how densely you place enemies.

Enemies need to be killable in different numbers of hits. If everything dies in three, the multiplier never gets a chance to matter. A mix of 2, 3 and 6 health means the combo you built on the weak ones pays off on the tough one — that's the loop your mechanic wants.

Getting hit should hurt twice. It costs health and your combo. That's already wired (rows 3 and 4), and it's the reason dashing through danger rather than fighting through it is a real choice. Lean into it — invulnerable dashes plus combo-on-hit-taken means skilled play looks like continuous motion.

Don't add a block or a parry. You have dash-invulnerability, which does the same job while keeping the player moving. A block button would slow the game down and fight against everything else you've built.

Match your animation length to MeleeAttack's timings. 0.06 + 0.1 + 0.14 = 0.3 seconds. This is the single most common thing that makes a combat game feel wrong — a swing animation that outlasts its hitbox. When you get to animation, either trim the clip or switch on Use Animation Events and place EnableHitbox() / DisableHitbox() on the actual frames. The second option is how professionals do it and it's easier to tune.


14. Common problems

What you see What's wrong
Attack does nothing Hitbox not assigned, or not disabled at start, or teams the same
Attack hits through walls Hitbox child not on the Hitbox layer
Combo never goes up Row 3 not wired — AttackHitbox.OnHit → ComboCounter.RegisterHit
Combo never resets Row 4 not wired
Combo counts double You wired RegisterHit for a projectile as well — projectiles do it themselves
Multiplier doesn't seem to apply It does — test on a 6-health enemy. On a 3-health enemy the extra damage is invisible
Dash doesn't work Dash action missing from the input asset, or you're on cooldown
Can air dash forever Air Dashes set too high
Take damage while dashing Invulnerable During Dash unticked
No wall slide WallCheck not assigned, Wall Layer unset, or you're not holding toward the wall (Require Pushing Into Wall ✓)
Wall jump goes the wrong way That's correct — it pushes away from the wall and flips you
Wall jump immediately re-grabs Lock Time too short — raise to 0.2
Enemy stalls between hits Enemy Invulnerability Time isn't 0
Melee and shoot both fire ProjectileShooter is in PlayerInput mode — set it to Manual

15. Checklist