Lesson 10: VFX and Game Feel Polish
Audio gave your slice weight. VFX and motion answer the next question players ask without thinking: Did my action land? Was that reward important? This lesson keeps scope tiny—one pass of particles, trails, camera punch, and optional hit-stop—so you can ship juice without opening a month-long VFX rabbit hole.
Lesson Objective
By the end of this lesson you will have:
- Three reusable VFX prefabs (for example hit spark, death puff, pickup glint) built with the built-in Particle System
- Clear sorting so VFX draw above or behind gameplay on purpose (layers / order in URP 2D or equivalent for your setup)
- A CameraFeel (or similar) helper that can run short shake and micro time scale dips from gameplay events
- A five-minute juice checklist you can run before playtests
Why This Matters
Players forgive placeholder art longer than they forgive unreadable feedback. A 0.08 second freeze on a heavy hit, a trail on the player dash, and a one-shot particle on pickup alignment turn the same mechanics into something that feels intentional. You are not aiming for AAA cinematics—you are aiming for clarity plus delight.
If particles disappear in builds, our help note on Unity particle system not rendering is a good emergency reference.
Step-by-Step
Step 1 - Create a VFX folder and base prefab workflow
- Add folders such as
VFX/PrefabsandVFX/Textures(even if you start with Prototype textures). - Create an empty
GameObjectnamedVFX_HitSpark. - Add Particle System. Disable Looping; set Duration around
0.35and Start Lifetime around0.2–0.4. - Set Start Speed modest so sparks do not fly off-screen.
- In Shape, use Cone or Hemisphere with a tight angle for melee hits.
- Add Color over Lifetime alpha fade-out so the effect cleans itself up.
- Drag the object into
VFX/Prefabsto make a prefab. Instantiate it from code or a smallVFXPlayerwhen hits land.
Pro tip: Name color/curve presets in the Particle System so you can copy modules between prefabs without re-tuning from scratch.
Step 2 - Trails for motion reads
- On the player weapon tip, projectile root, or dash ghost object, add Trail Renderer.
- Set Time short (
0.08–0.2) for snappy motion; longer for magic streaks. - Match Material to your pipeline (URP Unlit or Particles/Unlit family) so trails are cheap and visible.
- If trails flicker through floors, slightly offset the trail transform toward the camera or raise Min Vertex Distance.
Step 3 - Sorting and layers (2D-focused)
- Decide a rule: Gameplay characters on sorting layer
Characters, VFX onVFX_ForegroundorVFX_Background. - For world-space particles behind the player, lower Order in Layer or place them on a background sorting layer.
- For UI-attached bursts (level-up, mission complete), use Screen Space - Overlay Canvas particles or spawn world particles in front of the camera with a dedicated layer.
Step 4 - Camera punch (no package required)
- Create
CameraFeel.cson a Cinemachine-free rig or on your main camera if you are still using a simple follow. - Expose methods like
Punch(float amplitude, float duration)that run a Coroutine or tween that offsets localPosition with damped decay (perlin or simple sine decay both work). - Call
Punchon heavy hits, boss slams, or screen-clear pickups. Keep amplitude small; testers should feel it, not get motion sick.
Common mistake: Parenting the camera under a bouncing player transform, then adding punch on top—unparent or compensate so shake sums predictably.
Step 5 - Micro hit-stop (time scale)
- Add
HitStop(float duration, float timeScale = 0.05f)that setsTime.timeScaleto the low value, then restores withWaitForSecondsRealtime. - Use 0.06–0.12 seconds total for standard hits; shorter on rapid combos so inputs stay responsive.
- Guard with a cooldown so chained attacks do not stack into slideshow pacing.
Pro tip: Pair hit-stop with a single-frame white flash on the impacted enemy material for extra readability (toggle emission or swap to an unlit flash material for one frame).
Step 6 - Wire events from gameplay you already have
Reuse signals from Lessons 4–6:
- On damage dealt → spawn
VFX_HitSparkathitPoint,Punch, optionalHitStop. - On enemy death → slightly larger burst + short punch, no hit-stop if many enemies die at once (performance and nausea).
- On pickup collected → small upward particles + UI sound from Lesson 9.
Keep all timings data-driven ([SerializeField] float hitStopDuration) so designers tune without recompiles.
Step 7 - Performance pass (still a vertical slice)
- Cap max particles and emission rate on each prefab; prefer bursts over endless emitters.
- Share materials across VFX where possible to reduce batch breaks.
- Disable collision modules unless you truly need them—they are surprisingly expensive on mobile targets.
Mini Challenge
Add a perfect-dodge or counter window effect: 0.1s hit-stop, stronger punch, brighter particle tint when the player triggers a tight timing bonus. If you do not have that mechanic yet, fake it with a debug key for prototyping.
Troubleshooting
Particles invisible in Game view
Check Play On Awake, Simulation Space (world vs local), Culling, and renderer material compatibility with your pipeline.
Trails look like dotted lines
Lower Min Vertex Distance or increase movement speed sampling; verify the moving object actually translates each frame.
Hit-stop breaks UI animations
Drive critical UI with unscaled time (Time.unscaledDeltaTime) or pause UI tweens during freeze.
Too much juice, hard to read
Remove one layer at a time—usually hit-stop or shake—until testers can name what happened without guessing.
Recap
You shipped small, reusable VFX prefabs, trails that explain motion, layering rules that keep depth readable, and camera/time tricks that sell impact without rewriting combat code.
Next Lesson Teaser
Lesson 11 opens the Profiler and Frame Debugger so you can prove these effects are cheap—and catch the first real hotspots before you add more content.
FAQ
Should I use Visual Effect Graph now?
Not required for this course milestone. VFX Graph shines on larger teams and specific platforms; Particle System hits every target in your slice.
Cinemachine impulse sources?
If you already adopted Cinemachine, swap the manual punch for Impulse Source + listener—it is the production-grade version of Step 4.
Post-processing for punch?
A subtle chromatic aberration pulse can help, but add it only after particles and shake read clean—otherwise you are painting over confusion.
Related Links
Bookmark this lesson before your next playtest—you will tune timings live. Share it if someone on your team thinks juice means more bloom.