All project posts

Smashy Cubes

A playful Unity physics toy built for a tech test and later polished into a small release. You fling colorful cubes around a tray, smash them into hundreds of glowing fragments, and then watch a robot vacuum roll in to clean up the mess.

Introduction

  • Overview: Smashy Cubes is a small Unity physics toy where you toss RGB/CMY cubes around a tray, break them into fragments, and eventually get hassled by a robot vacuum to clean up. It’s closer to a digital fidget toy than a full game, built around the fun of smashing things and watching the pieces scatter.
  • Motivation: This started out as a Unity Engineer tech test for an American VR studio. The job didn’t work out in the end because of time zones, but I liked the prototype enough to polish and release it. What was meant to be a quick exercise stretched into a couple of evenings of polish, mostly because throwing cubes around and breaking them into tiny pieces was more entertaining than I expected.

Key features

  • Interaction and feel: Drag-and-fling controls with inertia and a bit of elastic overshoot. When the cube slows to a crawl, velocity resets so it never feels sluggish.
  • Fracturing: Cubes split into 8 smaller pieces on impact and can fracture down two generations, creating up to 384 fragments bouncing around at once.
  • Physics thresholds: Breaks aren’t automatic. Impact force is checked against cube mass, so big cubes need harder hits.
  • Readable feedback: Collisions trigger emission flashes and scaled audio, making it clear when a smash lands hard versus a soft bump.
  • Performance: Cubes and audio sources are pooled to avoid instantiation spikes. Materials are GPU-instanced, and references are cached to keep garbage collection low.
  • Flow: A central game flow handles transitions between smashing, cleanup, and victory. Systems hook into events via interfaces rather than referencing each other directly.
  • UI: Simple MVC-style UI with a progress bar that tweens smoothly and typewriter text for objectives.
  • Decoupled systems: Input and interaction are abstracted through small interfaces (IPressable, IDraggable, etc.), which makes swapping or adding behaviors straightforward.
  • Vacuum cleanup: Once the smashing ends, a robot vacuum uses a custom rigidbody attraction system to hoover fragments across the tray.
  • Stability: Framerate is locked at 60 FPS for predictable physics and consistent feel between editor and builds.

Key challenges & solutions

1. Fragment spawning and performance

  • Challenge: Fragmenting a cube into 8 pieces, with each piece able to fracture again, meant potentially 384 active rigidbodies and colliders at once. Naively instantiating them on impact caused GC spikes, stuttering, and draw call overhead.
  • Solution: Implemented a generic ObjectPool<T> for cubes and audio sources. CubeFragmentHandler requests pooled fragments, resets transforms, rigidbody state, and visuals before re-enabling. Combined with GPU instancing for shared materials, this kept frame times stable even under heavy smashing.

2. Resetting physics state cleanly

  • Challenge: Reusing pooled rigidbodies led to inconsistent behavior if velocity, angular velocity, or parenting weren’t reset correctly. Old forces sometimes bled into new spawns.
  • Solution: Each fragment is explicitly reset in CubeManager before activation: rigidbody velocity/angular velocity cleared, transform reassigned, generation incremented, and scatter impulse applied. This ensured fragments always behaved consistently regardless of pool history.

3. Emission and instancing

  • Challenge: Per-fragment emission flashes were needed for impact feedback, but modifying material instances directly broke GPU instancing and created unnecessary garbage.
  • Solution: CubeEmissionAnimator uses simple material swaps and short-lived emission intensity tweaks with minimal per-frame allocations. For a prototype this struck a balance between clarity and performance, while leaving room for a MaterialPropertyBlock approach if scaled up further.

4. Collision audio load

  • Challenge: With hundreds of fragments colliding, Unity’s audio pipeline quickly became saturated, producing noise and CPU spikes.
  • Solution: CubeAudioManager reuses a small pool of AudioSource components. It caps simultaneous collision sounds per frame and scales pitch/volume by impact force. This kept the mix clean and prevented audio from overwhelming performance.

5. Robot vacuum cleanup

  • Challenge: Designing a cleanup mechanic that pulled hundreds of fragments into a moving rigidbody without breaking the physics simulation or dropping frames.
  • Solution: RoombaAttractor applies a controlled force toward the vacuum within a radius, with falloff scaling by distance. Instead of teleporting fragments, rigidbody forces create a natural swirl. Coupled with pooled physics objects, this allowed cleanup to feel dynamic while remaining performant.

6. Consistent frame pacing

  • Challenge: Physics felt different between editor and standalone builds, especially during drag interactions. Uncapped framerates produced inconsistent motion.
  • Solution: FramerateController locks execution to 60 FPS. This ensured predictable physics behavior across environments and avoided subtle differences in drag feel, while also giving some breathing room for performance.

Future development

  • Input System migration with user-facing sensitivity settings
  • Optional timer and basic leaderboard for speed-run flavor
  • Staggered spawns and micro-delays on fractures for clarity
  • Unified pooled, world-space audio for vacuum and collisions
  • Exploration of DOTS Physics and Jobs/Burst for thousands of fragments

More project posts

Hire a senior Unity developer for XR, games & apps

9+ years experience building scalable, performant Unity solutions, XR, games, enterprise apps, prototypes, custom tools, and complex systems.

Available for freelance, consulting, or full project development. I reply within 1 business day.

Get in touch