A Tap-Cannon Colour-Matching Puzzle — Unity Template
Version 1.0 | Unity 6+ | URP
This asset is designed as a template and starting point for your own game development. It provides the core systems, architecture, and tools needed to build a tap-cannon colour-matching hypercasual game. You are expected to customize, extend, and modify this template to create your unique game. This is not a complete, ready-to-publish game — it's a foundation for developers to build upon.
Color Pixel Crush is a tap-cannon colour-matching puzzle where players tap cannons in a small tap-out grid to fire them onto a dock conveyor; docked cannons then fire bullets at a larger wall of coloured pixels. When a cannon's colour matches a pixel it destroys that pixel and counts down. Drain every pixel before any dock stalls to win the level. Cannons are only tappable when they have a clear path out (highlighted with an outline; blocked ones desaturate), and levels add wall obstacles and mystery (hidden-colour) cannons for depth. The game ships with three working boosters, a visual JSON-backed level editor, and an automatic level generator that can build levels procedurally or from real images — turning any picture into a playable colour-matching level.
Tap a cannon in the tap-out grid to send it sliding onto the conveyor. Once docked, it auto-raycasts its coloured bullet at the pixel wall and drains same-colour pixels until its ammo runs out.
Dock tiles cycle along a conveyor belt so cannons keep moving into and out of firing position. Timing matters — pick the right cannon for the column that needs draining next.
A two-pane Unity Editor window with ▲/▼ reorder, Add / Duplicate / Delete(confirm), green Save All, paint modes for both the fill wall and the cannon grid, and per-level booster counts.
Two modes — Procedural (concave difficulty curve, seed, ±7% jitter) and Image (quantizes any image into a level via K-means). Both ramp wall obstacles & mystery cannons with difficulty. Append-only, cancellable, red Delete-All. Default: 500 levels.
Block Shuffle (rearranges the picture blocks), Magic Select (pull out a blocked cannon), and Cannon Shuffle (reshuffle the cannon grid). Gated per-level, each with a one-time tutorial popup on first click.
Levels ship as plain JSON under Resources/Levels/Level_N.json. The Level Editor saves, reorders, and reloads them; the generator batches 500+ in minutes.
Assets/ColorPixelCrush/ contains Scripts, Editor, Prefabs, Resources/Levels, Scenes/GameNew.unity, Audio, Documentation, and PostProcessing.Assets/ColorPixelCrush/Scenes/GameNew.unity (the only scene). It ships fully set up — HUD, win/lose panels, the three boosters, the SoundManager, and post-processing are already wired and ready to play.Resources/Levels/.Tools > ColorPixelCrush > Auto Level Generator (Procedural or Image mode); to edit them use Tools > ColorPixelCrush > Level Editor.Once in Play mode, tap a cannon on the bottom tap-out grid; it slides onto the conveyor and docks. Docked cannons auto-fire same-colour bullets at the pixel wall. When every pixel is cleared, SoundManager.Instance.PlayLevelClear() fires and the next level loads automatically after the win panel is shown. If a dock stalls with unmatchable colours, the lose panel appears. Arrow-Left / Arrow-Right jump between levels in the Editor for quick iteration.
This package ships as a single top-level folder, ColorPixelCrush/, containing everything — game-specific scripts and content plus the canonical UI / booster / developer-mode scaffolding (originally distributed as the NewestDevUI package, now folded in for single-folder Asset-Store publishing). Its scripts live in Scripts/ (namespace HypercasualGameEngine), its prefabs in Prefabs/, its editor tools in Editor/, its icons in Textures/, and stub references in Samples/.
ConveyorBelt/ sprite set)
Every level carries a tap-out grid of cannons and a fill wall of coloured pixels. The player taps a cannon; if it can reach the bottom row via FLS.FindShortestPathToBottom it slides off the grid and lands on the nearest empty dock on the conveyor. Docked cannons raycast their bullet toward the wall; every frame a matching-colour FillItem sits in the bullet's path it is destroyed and the cannon's ammo decrements by one. When a cannon's ammo hits zero it is destroyed, a light particle bursts, and its dock frees up.
FLS.FindShortestPathToBottom) are tappable. Clickable cannons get a crisp outline; non-clickable ones desaturate toward grey, so it's always obvious what you can tap.LevelData.wallCells). Cannons must path around them, so walls shape which cannons are reachable.isMystery hides its colour behind a grey body with a “?” and is not clickable until an adjacent cannon is removed, which reveals its true colour.durationInLoop seconds; arrows visualise directionPhysics.Raycast forward; only same-colour FillItem hits countMoveFillItem coroutinesGameLevel.WinGame() → ColorPixelCrushGameManager.TriggerWin() (plays the win SFX, then shows the panel)GameLevel.LoseGame() → TriggerLose()Procedural and hand-made levels use 10 fixed colours from the TypeColor enum, each mapped to a material in ColorData.asset:
| Key | Colour | Key | Colour |
|---|---|---|---|
Yellow | Yellow | Blue | Blue |
Orange | Orange | Purple | Purple |
Brown | Brown | Pink | Pink |
Red | Red | Cyan | Cyan |
Green | Green | Magenta | Magenta |
Image-based levels carry their own palette. When the Auto Level Generator runs in Image mode, each level stores a per-level RGB palette (the dominant colours extracted from the source image) in LevelData.palette; at runtime the fill blocks and cannons are tinted to those exact colours, so the level reproduces the original picture. Levels with an empty palette fall back to the fixed 10 colours above.
fillGrid is destroyed. Star particles burst on the wall, SoundManager.Instance.PlayLevelClear() fires, the level index advances via LevelManager.AdvanceLevel(), and the next level loads automatically.CheckLose finds no path from any docked cannon to a matching pixel for one full second. The Retry button reloads the current level.Cannons bob on fire (AnimationFireCannon), arc-and-scale to zero on completion (AnimationDestroyCannon), and conveyor docks use Vector3.Lerp coroutines for smooth motion. Pixels fade to white before destruction (AnimationDestroyFillItem). Light and smoke particle systems accompany destroy events. No DOTween dependency — every animation is a hand-written coroutine.
Game-specific runtime scripts use the ColorPixelCrush.Scripts namespace. Editor tools live under ColorPixelCrush.EditorTools. Shared engine / UI scripts (LevelManager, SoundManager, ColorPixelCrushGameManager, LoseWinPanelManager, BoosterManager, DeveloperModeButton, DeveloperSettingsController, InputSystemCheck) live under HypercasualGameEngine.
| Script | Description |
|---|---|
GameLevel | Scene-level gameplay controller. Builds the fill and tap-out grids from LevelData, runs the conveyor loop coroutine, handles cannon tap/slide/dock motion, fires raycasts on behalf of docked cannons, and triggers WinGame/LoseGame. |
Cannon | Cannon entity. Holds typeColor, amount, line renderer, and two mesh renderers. CheckRayCast() is the auto-fire loop. CanTap drives the clickable outline + colour fade; SetupMystery/Reveal handle hidden-colour cannons; SetMagicCandidate drives the Magic-booster pulse. |
Dock | Dock tile. Holds the Cannon slot reference and its number label. |
FillItem | Pixel cell on the fill wall. Carries typeColor, IsFilled, and the MeshRenderer used for the destroy-fade animation. |
FLS | Floodfill / shortest-path helper. FindShortestPathToBottom answers whether a tapped cannon can exit the tap-out grid. |
InputManager | Touch / mouse raycast handler. Picks cannons whose CanTap is true and forwards to GameLevel.MoveCannonOutOfTapOutGrid. |
ColorData | ScriptableObject mapping TypeColor values to pixel materials and cannon bullet materials. |
LevelData | Serialisable level descriptor. Fields: grid sizes, cannonDatas (incl. isMystery), fillDatas, the three booster counts, plus palette (per-level image colours) and wallCells (wall obstacles). |
ImageQuantizer | Static K-means++ utility that turns a source image into a grid of palette indices + a dominant-colour palette. Used by the Auto Level Generator's Image mode to build levels from real pictures. |
OutlineController | Reference implementation of the position-based inverted-hull outline (the same pattern Cannon uses for its clickable highlight). Loads PixelOutline via Resources.Load so it survives WebGL / IL2CPP shader stripping. |
| Script | Description |
|---|---|
LevelManager | Static loader. Editor reads Level_N.json directly from Assets/ColorPixelCrush/Resources/Levels/; runtime uses Resources.Load<TextAsset>. Tracks progression under PlayerPrefs key ColorPixelCrush_CurrentLevel. |
SoundManager | Singleton audio hub. One AudioSource, masterVolume, Play* methods including the four required by NewestDevUI's BoosterManager: PlayBlocked, PlayBoosterShuffle, PlayBoosterBomb, PlayBoosterUnlock. |
ColorPixelCrushGameManager | [DefaultExecutionOrder(-100)] scene orchestrator. Replaces GameLevel.levelData with the JSON-loaded level before GameLevel.Start runs (so GameLevel needs no edits), initialises BoosterManager, owns the arrow-key dev navigation, and routes win/lose through TriggerWin/TriggerLose so PlayLevelClear/Fail fires exactly once. |
LoseWinPanelManager | Ships in NewestDevUI. Owns the Win / Lose panels; LoadNextLevel() calls LevelManager.AdvanceLevel() before SceneManager.LoadScene so progression sticks. |
BoosterManager | Three boosters — Block Shuffle, Magic Select, Cannon Shuffle — with per-level unlock gates, popup-before-can-gate (pitfall #31), and first-use tutorial popups keyed in PlayerPrefs. Effects call into GameLevel (ShuffleFillBlocks / SetMagicMode / ShuffleCannons). |
DeveloperModeButton / DeveloperSettingsController | Ships in NewestDevUI. In-game dev panel with Shift+U/W/L/R hotkeys. |
InputSystemCheck | [InitializeOnLoad] editor warning; blocks Play if Active Input Handling is set to “Input System (New)” only. |
| Script | Description |
|---|---|
LevelEditorWindow | Tools > ColorPixelCrush > Level Editor. Two-pane editor: drag-drop a reference image to build a level, edit the per-level palette live, paint fill/cannon/wall cells, live completability validation + a Randomize-Shooters fix. Saves JSON to Resources/Levels/Level_N.json. |
AutoLevelGeneratorWindow | Tools > ColorPixelCrush > Auto Level Generator. Procedural + Image modes, append-mode, cancellable, 500 by default, seed control, ramping walls/mystery, red Delete-All. |
ColorPixelCrushWelcomePopup | Tools > ColorPixelCrush > Welcome. Auto-opens once per session (with a “don't show on startup again” opt-out); buttons for the documentation, the Level Editor, the Auto Level Generator, and an Asset Store review link. |
InputSystemCheck | Editor safety helper: warns if Active Input Handling is not set to Both. |
Open with Tools > ColorPixelCrush > Level Editor. The left pane lists every Level_N.json on disk with ▲/▼ reorder, Add, Duplicate, Delete(confirm), green Save All, and Reload. The right pane edits the selected level's grid dimensions, booster counts, fill grid, and cannon grid.
Each grid is Y-flipped visually so row 0 draws at the top. Click a cell in Colour-paint mode to stamp the current colour; None-mode clears. In the cannon grid the amount label appears on each cannon.
Save All writes every entry's JSON to disk and clears the “*” dirty marker. Delete removes the JSON and renames the remaining files so there are never gaps in the sequence.
Open with Tools > ColorPixelCrush > Auto Level Generator. Pick a Mode at the top, set the count/seed/sizes, and Generate. The generator appends — it never overwrites an existing Level_N.json. The red Delete ALL levels button (with confirm) clears Resources/Levels/ for a clean rebuild.
Carves a random multi-colour blob into the fill grid. The difficulty curve is concave: t = clamp((oneBased - 1) / 12, 0, 1), then raised to 0.55, so it reaches 80%+ difficulty by level ~12 regardless of total count. The colour palette grows with difficulty (1 colour → up to all 10), and ±7% jitter keeps consecutive levels from feeling templated.
Drop .png/.jpg images into Assets/ColorPixelCrush/Resources/AutomaticLevelGeneratorImages/, set Mode = Image, and Generate. Each level picks one image (cycling) and runs it through ImageQuantizer (K-means++): the image becomes the fill-grid picture and its dominant colours become the level's palette. The result is a playable level that reproduces the original image. Grid size and colour count both ramp with difficulty.
Both modes ramp wall obstacles and mystery cannons with difficulty (tunable via the Wall ratio / Mystery ratio sliders). Cannon placement guarantees every colour's total cannon ammo equals its pixel count on the wall, so the per-colour supply always matches demand. Mystery cannons are only placed where a neighbour can reveal them, and exit-edge cannons stay non-mystery so the level always has a clickable starting move — every generated level is structurally solvable.
Three fully-implemented boosters, gated per-level. Counts come from LevelData.shuffleBoosterCount / bombBoosterCount / unlockBoosterCount (the field names are historical; the effects below are what they drive). The first click of each booster shows a one-time tutorial popup (Popup_Powerup_Picker prefab); the popup fires before any can-run check so the player always sees it on first click regardless of board state (pitfall #31).
GameLevel.ShuffleFillBlocks().GameLevel.SetMagicMode() + InputManager.GameLevel.ShuffleCannons().Unlock levels are zero-based on BoosterManager.booster1/2/3UnlockLevel; the HUD shows lvl N on buttons that are not yet unlocked, and clickable cannons fade/outline so the boosters' effects are easy to read. The BoosterPopupShown_* PlayerPrefs keys persist the “already saw the popup” state across sessions.
The booster effects live on the gameplay layer in GameLevel.cs — ShuffleFillBlocks() (Block Shuffle), SetMagicMode() (Magic Select, with the pull handled in InputManager), and ShuffleCannons() (Cannon Shuffle). BoosterManager.OnBooster1/2/3Clicked call into them. To change a booster, edit the matching GameLevel method; to swap which booster does what, re-point the calls in BoosterManager.
The 10 fixed colours map TypeColor → materials in ColorData.asset (Inspector-editable). Add more by extending the TypeColor enum in LevelData.cs and adding a material + mapping. Image-based levels ignore the fixed palette — they tint at runtime from each level's own palette, generated by Image mode. To re-roll an image's colours, regenerate that level (the K-means seed changes per generation).
Drop new clips into Assets/ColorPixelCrush/Audio/ and assign them on the SoundManager GameObject in GameNew.unity (Inspector fields for LevelClear, LevelFail, Blocked, Success*, Fail*, Pop*, Switch*). The clips ship pre-wired, so you only touch the fields you replace.
Edit > Project Settings > Player. The template ships with Unity's default splash logo; swap for your own artwork before release. Bundle Version starts at 0.1.0; bump per release.
The PixelOutline shader exposes _OutlineColor and _OutlineWidth. The shared material is created at runtime by OutlineController; edit the defaults in that script or create a Material instance and assign it per object.
The scene's Global Volume references Assets/ColorPixelCrush/PostProcessing/HC-PostProcessing-Volume.asset at weight 0.8. To change the look, edit the VolumeProfile directly; to re-weight, change the weight property on the Volume component in the scene.
Questions, bug reports, or feature requests? Email ragendom@gmail.com — we're happy to help.
For updates and more hypercasual templates, visit the HyperCasual Game Engine listing on the Unity Asset Store. The engine's InputSystemCheck, LoseWinPanelManager, and DeveloperSettingsController ship identically across every template in the catalog — bug fixes there propagate to every game.