Car Parking Jam

A Car-Routing Parking Puzzle Game — Unity Template

Version 1.0 | Unity 6+ | URP

🌟 This asset was made with the HyperCasual Game Engine!   Check it out — mobile puzzle templates & more. Click here to learn more ➔

Important: Template / Starting Point

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 car-routing parking puzzle 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.

Overview

Car Parking Jam is a car-routing parking puzzle game where players tap colored cars on a grid to drive them out to a row of parking slots, where matching-colored passengers automatically walk from their queues and board. Fill every car with passengers to send it off and clear the level. The game features 3D animated passengers, a built-in level editor, an automatic level generator, and a booster system.

Tap-to-Drive Puzzles

Intuitive touch/click controls — tap any reachable car on the grid to route it to the next free parking slot. Matching colored passengers automatically walk from their queue and board.

Level Editor

Full Unity Editor window for designing levels with a visual grid painter — place colored cars, configure passenger queues, parking slots, locked VIP slots, and waypoint paths.

Auto Level Generator

Batch-generate hundreds of playable levels with configurable difficulty curves, grid sizes, color counts, passenger-queue depths, and parking-slot configurations.

Booster System

Three in-game boosters — Unlock Slot (opens a locked parking space), Shuffle (randomizes grid cars), and Balloon Pick (fly any car straight to a free parking slot) — with tutorial popups and usage tracking.

100 Levels Included

Ships with 100 pre-generated levels on a progressive difficulty curve, ready to play out of the box. Generate more at any time with the auto generator.

Built-In Monetization Hooks

Provider-agnostic AdsManager facade with a Dummy provider out of the box. Plug in AdMob (or any SDK) in one file without touching gameplay code.

Getting Started

Requirements

Installation

  1. Import the Car Parking Jam package into your Unity project
  2. Ensure the project is set to use the Universal Render Pipeline (check Edit > Project Settings > Graphics)
  3. Open the game scene at Assets/CarParkingJam/Scenes/GameNew.unity
  4. Press Play to test the first level

Quick Test

Once in Play mode, tap any clickable car on the grid (front-row cars and any car whose path to the front is clear). The car drives through the grid, out to the back row, then parks in the next free slot. Matching-colored passengers in the queues automatically walk over and board it. When every car is filled and all passenger queues are empty, the level is cleared and the next level loads automatically.

Folder Structure

CarParkingJam/ │ ├── Art/ │ ├── Animations/ — Animator controllers and UI animation clips │ ├── Materials/ — Shared materials: cars, ground, UI elements │ ├── Models/ — 3D models (.fbx): cars, passengers, environment │ └── Textures/ — UI textures (booster buttons, icons, lock sprites) │ ├── Audio/ — All sound effects (.wav): Switch, Pop, Success, Fail, LevelClear, LevelFail │ ├── Documentation/ — This documentation file │ ├── Editor/ — Level Editor, Auto Level Generator, Welcome popup │ ├── ParkingLevelEditorWindow.cs — Visual level designer │ ├── ParkingLevelGenerator.cs — Automatic batch level generator │ └── CarParkingJamWelcomePopup.cs — Welcome popup on project open │ ├── Fonts/ — TextMeshPro fonts used by the HUD │ ├── PostProcessing/ — URP Global Volume profile │ ├── Prefabs/ — CAR, Car Tile, Grid Elements, Passenger, Particle effects │ └── Global/ — Shared UI prefabs: GameHUD_Panel, LoseWinPanel, GameOverPanel, Booster-Popup │ ├── Resources/ │ ├── CarOutline.shader — Hand-written HLSL outline shader for clickable cars │ ├── PeopleOutline.shader — Outline shader for passengers │ └── Levels/ — 100 level JSON files (Level_1.json ... Level_100.json) │ ├── Scenes/ │ ├── GameNew.unity — The single playable scene │ └── MainLevel.unity — Sandbox scene (optional) │ ├── Textures/ — Shared UI textures (booster icons, radial-shine, lock) │ └── Scripts/ — All runtime scripts ├── ParkingGameManager.cs — Main gameplay orchestrator ├── ParkingLevelManager.cs — Static JSON level loader ├── ParkingLevelData.cs — Level data serialization structures ├── ParkingLevelBuilder.cs — Builds scene content from level data ├── ParkingLevelLoader.cs — Static helpers for reload / advance / jump ├── CarGridBuilder.cs — Car grid construction & cell lookup ├── CarGridCell.cs — Single-cell state (occupancy, pathfinding gCost) ├── ParkingCar.cs — Car entity: click, drive, park, balloon fly ├── ParkingSlotManager.cs — Parking slots, locked/unlocked visual, gradient glow ├── PathfindingManager.cs — Grid pathfinding & cost propagation ├── PassengerGridBuilder.cs — Passenger-queue grid construction ├── PassengerGridCell.cs — Passenger-queue cell data ├── PassengerMovement.cs — Passenger walking & boarding ├── PassengerQueueManager.cs — Queue boarding coroutine & win detection ├── CarColor.cs — Enum of car/passenger colors ├── CarColorLibrary.cs — ScriptableObject color-to-material mapping ├── AudioSettingsManager.cs — Volume / mute persistence ├── FpsDisplay.cs — On-screen FPS counter (optional) ├── SaveKeys.cs — PlayerPrefs key constants ├── TutorialPanel.cs — Per-level tutorial popup helper ├── Vibration.cs — Haptic feedback wrapper ├── BoosterManager.cs — 3-booster state machine & popups (HypercasualGameEngine) ├── LevelManager.cs — Generic level index tracker (HypercasualGameEngine) ├── LevelData.cs — Generic booster-count container (HypercasualGameEngine) ├── SoundManager.cs — Singleton audio facade (HypercasualGameEngine) ├── LoseWinPanelManager.cs — Win/lose panel + auto-advance (HypercasualGameEngine) ├── DeveloperModeButton.cs — Dev panel toggle (HypercasualGameEngine) ├── DeveloperSettingsController.cs — Dev panel controls (HypercasualGameEngine) └── CameraSwitcher.cs — Multi-camera helper (HypercasualGameEngine) Plugins/ — Reserved for iOS/Android native plugins (e.g. AdMob SDK) Settings/ — URP render pipeline assets TextMesh Pro/ — TextMeshPro essentials TutorialInfo/ — Unity URP template starter assets

Gameplay

Core Mechanics

Each level features a grid of color-coded cars, a set of passenger queues above the grid, and a row of parking dock slots between them. The goal is to clear all passengers from the queues by filling every outgoing car with matching-colored passengers.

Car Colors

The game supports nine predefined car/passenger colors defined in the CarColor enum:

Color Key Color Reference Hex
Red Red #FF4757
Green Green #7BED9F
Blue Blue #48DBFB
Yellow Yellow #ECCC68
Orange Orange #FFA502
Violet Violet #BC8CFF
Pink Pink #FF6B81
Brown Brown #A0522D
Gray Gray #A4B0BE

The palette is defined by the Materials you assign to CarColorLibrary; the hex values above are the reference look used by the shipped art.

Win & Lose Conditions

Animations

Passengers have three animation states: idle (waiting in the queue), run (walking from the queue to the docked car), and boarded (seated inside the car). Cars animate with smoothed path following, rotate toward their heading, and play a smoke-burst effect when the "hidden" cover is revealed. The Balloon Pick booster adds a rise → fly → drop sequence with a soft balloon sprite and particle plume.

Scripts Reference

Gameplay scripts live in the global namespace under Assets/CarParkingJam/Scripts/. Reusable engine scripts live in the same Assets/CarParkingJam/Scripts/ folder under the HypercasualGameEngine namespace.

Core Gameplay

Script Description
ParkingGameManager The orchestrator. Tracks game state (stopGame, isPowerupActive, carMovingCount), bridges the engine LevelManager to ParkingLevelManager, wires booster callbacks, handles keyboard shortcuts, and triggers win/lose flow.
ParkingLevelManager Static level loader. Loads every Level_N.json from Resources/Levels/, sorts by index, and tracks progression via the ParkingJam_CurrentLevel PlayerPrefs key. Exposes editor-only save/load helpers.
ParkingLevelData Serializable POCO: grid size & spacing, cell list, passenger queue columns, parking slot count, locked-slot indices, waypoint paths, and per-level booster counts.
ParkingLevelBuilder Builds the runtime scene from ParkingLevelData: spawns grid tiles, places cars, builds passenger queues, activates parking slots, applies locks, and lays out waypoints. Invoked on Start by BuildCurrentLevel().
ParkingLevelLoader Thin static helpers for scene reload, level advance, and jump-to-level. Used by win flow, dev panel, and keyboard shortcuts.
CarGridBuilder Car-grid construction and lookup. Holds the 2D CarGridCell cache and exposes GetGridCell(col, row) / GetCar(col, row) to the rest of the system.
CarGridCell Single grid cell. Stores row/column, occupancy flags (isOccupied, isEmpty, blockedPath), assigned CarColor, reference to the spawned car, and A*-style gCost used by pathfinding.
ParkingCar Car entity. Handles OnMouseDown click routing, waypoint following, smoke/balloon effects, outline toggling, passenger counter display, parking finalization (SetParent + localPosition = zero), and reverse-move when a car re-enters the grid.
ParkingSlotManager Parking-row state. Tracks parkingPositions, parkingStatus (per-slot color), maximumParkingCount, and lockedParkingSlots. Renders the gradient-glow effect on slot departure and the pop-scale animation on booster unlock.
PathfindingManager Grid pathfinding. Maintains per-cell gCost, propagates costs outward from the front row, builds car paths on click, builds exit paths on departure, and updates reachability for hidden/blocked cars.
PassengerGridBuilder / PassengerGridCell Construct the N-column, multi-row passenger grid with per-column spacing. Each cell stores row/column for queue-entry logic.
PassengerMovement Passenger entity. Holds color + queue index, applies the correct material, and plays the walk → board animation sequence when summoned by PassengerQueueManager.
PassengerQueueManager Coroutine TryBoardPassengers() scans each queue front against every docked car and sends matching passengers. Handles queue advance, queue empty detection, and level-win trigger.
CarColor / CarColorLibrary The CarColor enum plus a ScriptableObject mapping each color to a car material and a passenger material. Used by every spawn path.

Engine Scripts (HypercasualGameEngine)

Script Description
BoosterManager Reusable 3-booster manager. Handles lock/unlock by level, consume/refund counts, toggle mode (booster C), tutorial popups keyed in PlayerPrefs, and a 4-state HUD button UI (Locked / Usable / Depleted / Active). Exposes OnBoosterAUsed, OnBoosterBUsed, OnBoosterCActivated, OnBoosterCDeactivated for per-game wiring.
LevelManager Generic level index tracker used by BoosterManager. ParkingGameManager mirrors ParkingLevelManager's index into it on Start, so booster unlock levels compare against the real parking level.
LevelData Generic container for boosterACount/B/C. Registered in bulk from ParkingLevelData during the bridge.
SoundManager Singleton audio facade. One AudioSource + PlayOneShot per call site. Exposes PlayCarTap, PlayCarPark, PlayCarExit, PlayWrongCar, PlayBlocked, PlayBooster, PlayPassengerBoard, PlayButtonClick, PlayLevelClear, PlayLevelFail.
LoseWinPanelManager Win / lose panel controller. Auto-discovers child panels by name, drives the auto-advance coroutine, rotates the radial-shine decor, and wires the retry button. Patched to call ParkingLevelManager.AdvanceLevel() on next-level load.
DeveloperModeButton / DeveloperSettingsController Corner Dev-Mode button toggles a panel with buttons for: next / previous / reload level, trigger win / lose, unlock all boosters, refill boosters, reset tutorial popups, visual theme cycling.
AdsManager Provider-agnostic ads facade. ShowBanner, HideBanner, ShowInterstitial(onClosed), ShowRewardedVideo(onFinished), IsRewardedVideoReady. Ships with a Dummy provider — swap to AdMob in one file.
MonetizationSettings ScriptableObject holding provider selection (Dummy / UnityAds / AdMob), platform-specific ad unit IDs, interstitial cadence, privacy & terms URLs.
MonetizationInitModule Scene component: loads MonetizationSettings (inspector or Resources), boots AdsManager on Awake, optionally shows a banner immediately.

Editor Scripts

Script Description
ParkingLevelEditorWindow Unity Editor window (Tools > Car Parking Jam > Level Editor) for visually designing levels. Left panel lists levels with add / duplicate / reorder / delete / save-all. Right panel hosts grid painter, passenger-queue editor, parking slot count / lock editor, waypoint path editor, and booster-count fields.
ParkingLevelGenerator Unity Editor window (Tools > Car Parking Jam > Auto Level Generator) for batch-generating levels with configurable difficulty curves.
CarParkingJamWelcomePopup Welcome popup that appears on project open (via [InitializeOnLoadMethod]). Prompts for an Asset Store review and cross-promotes the HyperCasual Game Engine. Can be permanently dismissed.

Level Editor

Opening the Level Editor

In the Unity menu bar, go to Tools > Car Parking Jam > Level Editor. This opens a dedicated Editor window — no need to enter Play mode.

Features

Paint Modes

Mode Left Click
None No painting — click cells to inspect their contents
Place Place a colored car at the clicked cell. Clicking an occupied cell replaces its color with the currently selected one.
Erase Remove whatever car is at the clicked cell, leaving it empty.

Level Storage

All levels are stored as individual JSON files in Assets/CarParkingJam/Resources/Levels/ with the naming convention Level_1.json, Level_2.json, etc. They are loaded at runtime via Resources.LoadAll<TextAsset>("Levels").

Automatic Level Generator

The Automatic Level Generator is an Editor tool that batch-generates playable parking-puzzle levels procedurally. It uses configurable difficulty curves, pathfinding-aware car placement, and balanced passenger-queue distributions to create varied, solvable levels.

Opening the Tool

In the Unity menu bar, go to Tools > Car Parking Jam > Auto Level Generator. This opens a settings window where you can configure all parameters before generating.

Settings

Setting Description
Levels to Generate How many new level files to create. New levels are appended after existing ones (never overwrites).
Grid Rows / Columns (Min & Max) Range for randomizing the grid dimensions of each level. Controls how much space cars have to route through.
Color Count (Min & Max) Range for the number of distinct colors used per level. Default: 2–5.
Grid Fill (Min & Max) Fraction of grid cells filled with cars. Higher fill = denser puzzle, tighter routing.
Hidden Car Ratio Fraction of cars that start "covered". Revealed with smoke when reachable.
Passenger Queue Columns Number of passenger queue columns above the parking row. Default: 3.
Passenger Queue Depth (Min & Max) How many passengers stacked in each queue column. Sets total passengers per level.
Parking Slots (Min & Max) Range for the number of parking dock slots per level. Default: 3–6.
Locked Slots (Min & Max) Range for how many slots start locked. Only appear after the Locked-Slot intro level. Default: 0–1.
Lock Intro After Level Locked slots only start appearing after this level number. Default: 10.
Booster Counts (Unlock / Shuffle / Balloon) Min/Max booster uses per level. Inverted difficulty: more uses on early levels, fewer on harder levels.

How It Works

  1. Configure settings — adjust all parameters in the Editor window
  2. Click "Generate Levels" — the tool detects existing levels and appends new ones
  3. For each level, the generator:
    • Randomizes grid size, color count, and fill density within your ranges
    • Interpolates difficulty based on position in the batch (easier at low levels, harder at high levels)
    • Places cars on a shuffled fill pattern that guarantees at least one front-row clickable car
    • Generates passenger queues whose color totals exactly match the total car capacity per color
    • Distributes passengers across queue columns in a shuffled round-robin pattern
    • Picks the next free parking-slot count and locked-slot positions from the active ranges
    • Exports a JSON level file to Resources/Levels/

Non-Destructive

The generator never overwrites existing level files. It always starts numbering from the next available index (e.g., if Level_100 exists, new levels start from Level_101). Use the "Delete ALL Levels" button if you want to start fresh.

Boosters

The game includes three booster abilities that players can activate during gameplay. Each booster has a configurable number of uses per level (set in the level JSON data) and an optional tutorial popup that appears on first use.

Booster Effect Activation
Unlock Slot Unlocks the leftmost locked parking slot, making it available for incoming cars. The lock icon fades out and the slot tile pops with a scale-bounce animation. Useful when all usable slots are full but locked ones remain. Tap the Unlock button (Booster-Button-1). Consumes one use immediately. Automatically refunds the use if there are no locked slots to open.
Shuffle Randomly rearranges every non-hidden car on the grid using a smooth arc-swap animation. Changes which cars are front-row and which paths are reachable, often turning a stuck board into a playable one. Tap the Shuffle button (Booster-Button-2). Consumes one use immediately.
Balloon Pick Activates a special toggle mode where the player can tap any non-hidden car on the grid, even one that would normally be blocked. The selected car lifts with a balloon, flies through the air, and drops into the next free parking slot. Its grid cell becomes empty and is re-propagated into the pathfinding map. Tap the Balloon button (Booster-Button-3) to toggle the mode on. All non-clickable cars flash with a pulse to indicate they are now selectable. Tap again to cancel without consuming a use. A use is consumed only when you actually pick a car.

Booster Buttons

Booster buttons are found in the GameHUD_Panel/BottomHolder in the scene UI. Each button has:

Cheat Mode

Press the U key during gameplay to unlock all boosters and refill their usage counts. Press Right Arrow / Left Arrow to jump to the next/previous level. These shortcuts are useful for testing.

Customization Guide

Adding New Colors

To add a new car/passenger color:

  1. Open CarColor.cs and add a new entry to the enum:
    public enum CarColor { Red, Green, Blue, Yellow, Orange, Violet, Pink, Brown, Gray, // Add your custom color before Null/Lock: Teal, Null, Lock }
  2. Create a new car Material in Art/Materials/ with the desired color, plus a matching passenger Material
  3. Open the ColorManger.asset (CarColorLibrary) ScriptableObject and add a new entry mapping CarColor.Teal to those materials
  4. Re-save every level via Tools > Car Parking Jam > Level Editor > Save All to Disk so the JSON levels recognize the new color as a valid option

New colors are automatically available in the Level Editor, Auto Level Generator, and at runtime.

Adjusting Grid Visuals

The grid layout is controlled by CarGridBuilder and ParkingLevelBuilder. Key properties:

Modifying Car Visuals

Car rendering is handled by the ParkingCar component. Each car prefab includes:

Modifying Passenger Visuals

Passengers use SkinnedMeshRenderer with material coloring and Animator for character animations. To change the character model, replace the prefab mesh and ensure the Animator has triggers for the walk and seated states used by PassengerMovement.

Modifying the Lock Visual

Locked parking slots are indicated by a gray lock sprite overlay plus a dark-gray tile tint. Both are configured at runtime by ParkingSlotManager.ApplyLockedVisual(). To change the lock icon, replace the sprite on the Lock child of any Parking_Tile GameObject. To change the locked tile color, edit the LOCKED_TILE_COLOR constant in ParkingSlotManager.cs.

Adding New Boosters

New boosters can be added by following the existing pattern in BoosterManager.cs:

  1. Add booster state fields (use count, active flag, UI references)
  2. Wire up the button in HookUpExistingBoosters() following the HookUpBoosterButton() pattern
  3. Implement the booster logic in a new click handler method (e.g., OnMyBoosterClicked())
  4. Add a booster-count field to ParkingLevelData so it can be configured per level, and propagate it through the SyncEngineLevelManager() bridge in ParkingGameManager
  5. Update UpdateBoosterUI() to handle the new booster's lock/unlock/count display

Monetization (Ads)

The project ships with a stub AdsManager that runs in Dummy mode so the game works out of the box. To ship real ads:

  1. Create a MonetizationSettings asset: right-click in Assets/CarParkingJam/Resources/ → Create > Hypercasual > Monetization Settings
  2. Drop a MonetizationInitModule component on a root GameObject in GameNew.unity and reference the asset
  3. Import the Google Mobile Ads SDK and the External Dependency Manager
  4. Switch the asset's provider fields from Dummy to AdMob and fill in your real ad-unit IDs (leaving Google's test IDs as placeholders during development)
  5. Add MODULE_ADMOB to Project Settings > Player > Scripting Define Symbols and wire the real SDK calls inside AdsManager.cs

Game code never imports GoogleMobileAds.* directly — it only calls AdsManager. This keeps the ad provider swappable in a single file.

JSON Level Format

Each level is a JSON file with the following structure:

{ "levelNumber": 1, "boosterACount": 3, // Unlock Slot "boosterBCount": 3, // Shuffle "boosterCCount": 3, // Balloon Pick "gridRows": 3, "gridColumns": 4, "columnSpacing": 0.6, "rowSpacing": 0.9, "cells": [ { "row": 0, "column": 1, "cellType": "occupied", "carColor": "Violet", "hidden": false } // ... more cells ... ], "passengerQueueColumns": 3, "passengerGridRows": 5, "passengerColumnSpacing": 0.7, "passengerRowSpacing": 0.5, "passengerQueues": [ { "colors": [ "Violet", "Yellow", "Red" ] }, { "colors": [ "Yellow", "Violet", "Gray" ] }, { "colors": [ "Gray", "Violet", "Yellow" ] } ], "parkingSlotCount": 4, "lockedParkingSlots": [ 3 ], "pathToParking": [ { "x": -0.97, "y": -0.16, "z": 0.64 } // ... more waypoints ... ], "pathToOutside": [ { "x": -0.97, "y": -0.16, "z": 0.64 }, { "x": 3.80, "y": -0.16, "z": 0.64 } ] }

The cells array defines grid cars (sparse: only non-empty cells). Each cell has row, column, cellType ("occupied" or "empty"), a carColor string matching the CarColor enum, and a hidden flag. The passengerQueues array has one entry per queue column with a list of color strings from front to back. lockedParkingSlots is a zero-indexed list of parking slot indices that start locked. The two path* arrays define the world-space waypoints cars follow from the grid to the parking row and from the parking row off-screen.

Support

Common Issues

Issue Solution
No levels load / empty grid appears Ensure JSON level files exist in Assets/CarParkingJam/Resources/Levels/ with the naming convention Level_1.json, Level_2.json, etc. Use the Auto Level Generator to create levels if the folder is empty.
Pink/magenta materials on objects The project requires URP. Go to Edit > Project Settings > Graphics and ensure a URP Render Pipeline Asset is assigned. Check that the Settings/ folder contains valid URP assets.
Cars can't be clicked Go to Project Settings > Player > Other Settings > Active Input Handling and set it to Both. Legacy OnMouseDown raycasts are disabled if you select "New Input System only".
Car outline not showing The outline effect requires the CarOutline.shader file in Assets/CarParkingJam/Resources/. If missing, add it back or update ParkingCar.SetOutlineVisible() to use a different shader.
Passengers don't walk to cars Check that PassengerQueueManager.TryBoardPassengers() is being triggered after every successful car park. Ensure queue columns are configured and the passengerQueues list in the level JSON is non-empty.
Booster buttons don't respond Ensure the GameHUD_Panel/BottomHolder hierarchy contains children named Booster-Button-1, Booster-Button-2, and Booster-Button-3. Each needs a Button component. If you added a Canvas component for sorting order, you must also add a GraphicRaycaster.
Locked slot has no lock icon Some Parking_Tile GameObjects in the scene may be missing their Lock child. ParkingLevelBuilder.EnsureLockIcon clones a sibling's Lock at runtime to handle this, but for a clean scene add a Lock child (matching the existing ones) under every Parking_Tile you want to be lockable.
4th parking slot feels unusable The slot is probably locked by the level JSON. Use the Unlock Slot booster in-game, or remove the index from lockedParkingSlots in that level's JSON file.
Level Editor shows empty grid Click "Reload from Disk" in the Level Editor window, or ensure the Resources/Levels/ folder exists and contains valid JSON files.
Ads don't show at all Confirm a MonetizationInitModule exists in GameNew.unity with a valid MonetizationSettings reference, and the providers are set to AdMob (not Dummy). Dummy mode only logs to the console.

Tips

Contact Us

If you get stuck or have any issues, feel free to reach out to us at ragendom@gmail.com. We are happy to help!