A Crowd-Sorting Bus Puzzle Game — 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 crowd-sorting bus 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.
Bus Out Crowd Jam is a crowd-sorting puzzle game where players tap buses to dock them at parking slots, and matching colored people walk from the grid to their corresponding bus. Clear all people from the grid by filling every bus to win the level. The game features 3D animated characters, a built-in level editor, an automatic level generator, a booster system, and full AdMob ad integration via RagendomAds.
Intuitive touch/click controls — tap a bus in the queue to dock it at a parking slot. Matching colored people automatically walk to the bus and board it.
Full Unity Editor window for designing levels with a visual grid painter — place colored people groups, configure bus queues, parking slots, and VIP docks.
Batch-generate hundreds of playable levels with configurable difficulty curves, grid sizes, color counts, bus capacities, and parking slot configurations.
Three in-game boosters — Shuffle (rearrange bus queue), Pick Any (select any bus), and VIP Dock (unlock a VIP parking slot) — with tutorial popups and usage tracking.
RagendomAds monetization module with banner, interstitial, and rewarded video ads. Includes a Dummy provider for editor testing without a real device.
Ships with 500 pre-generated levels with a progressive difficulty curve, ready to play out of the box. Generate more at any time with the auto generator.
Edit > Project Settings > Graphics)Assets/Bus Out Crowd Jam/Scenes/SampleScene.unityOnce in Play mode, tap any bus at the front of a queue to dock it at an available parking slot. Matching colored people on the grid will automatically walk toward the docked bus and board it. When all buses are filled and all people have boarded, the level is cleared and the next level loads automatically.
Each level features a grid of color-coded people (grouped into "boxes"), a queue of color-coded buses arranged in columns, and a set of parking dock slots. The goal is to clear all people from the grid by filling every bus with matching colored passengers.
The game supports six predefined people/bus colors defined in the TypeColor enum:
| Color Key | Color | Hex Value |
|---|---|---|
Yellow |
Yellow | #ECCC68 |
Red |
Red | #FF4757 |
Green |
Green | #7BED9F |
Orange |
Orange | #FFA502 |
Purple |
Purple | #BC8CFF |
Blue |
Blue | #48DBFB |
People on the grid have four animation states: idle (default standing), run (triggered when moving toward a bus), sitDefault (seated inside a bus), and standUp (transitioning from seated to standing). Buses have a particle burst effect on completion and smooth movement animations when docking and departing.
Runtime scripts use the BusOutCrowdJam namespace. Editor scripts use the BusOutCrowdJam.Editor namespace.
| Script | Description |
|---|---|
GridManager |
Main gameplay controller. Initializes the grid of people from level data, manages parking dock slots, handles people movement and pathfinding to buses, bus filling logic, VIP dock locking/unlocking, win/lose detection, and win game animations. |
InputManager |
Handles touch and mouse input. Raycasts to detect bus taps, routes taps to either the normal docking flow or the Pick Any booster flow. Supports both Touchscreen and Mouse via the new Input System. |
TapOutManager |
Manages bus queue columns. Spawns buses from level data, tracks which bus is at the front of each column (tappable), handles bus removal and queue advancement, car outline highlighting, desaturation of non-tappable buses, and win condition checking. |
Car |
Bus entity component. Stores color type, passenger capacity, current fill count, references to boarded people, mesh renderer, particle system, and the text display for remaining capacity. |
People |
Person entity component. Stores grid position, animation state (run, standUp), skinned mesh renderer for material coloring, and pedestal reference. Controls character animations via Animator triggers. |
LevelManager |
Static class that loads level JSONs from Resources/Levels/ at runtime, tracks the current level index via PlayerPrefs, and provides methods to advance, go back, or jump to any level. Also provides editor-only save/load APIs. |
BoosterManager |
Manages all three boosters: Shuffle (randomizes bus queue positions with arc animation), Pick Any (toggle mode that lets player tap any bus, not just the front one), and VIP Dock (unlocks a locked parking slot). Handles UI state, counts, unlock levels, tutorial popups, and debug shortcuts. |
GameLevel |
Level initialization bridge. On Awake, loads the current level from JSON via LevelManager, configures active parking slots and their layout, initializes the grid and bus queues, locks VIP docks, and auto-creates a BoosterManager if missing. |
SoundManager |
Singleton audio system. Exposes named methods for each sound effect: PlayCrowdPeopleTap(), PlayCrowdPeoplePlace(), PlayCrowdBusComplete(), PlayBoosterUse(), PlayShuffle(), PlayDockUnlock(), PlayGameWin(), PlayGameOver(). |
LevelData |
ScriptableObject for level data. Contains grid dimensions, list of BoxData (colored people groups with positions), list of CarColumnData (bus queues), booster counts, parking slot count, VIP slot count, and bus column count. Also defines the TypeColor enum. |
LevelDataJson |
JSON serialization classes: JsonLevelData, JsonBoxData, JsonCarData, JsonCarColumnData, and GridPos. Provides bidirectional conversion between JSON and ScriptableObject formats. Also contains the BusCrowdColors helper class with the color palette. |
ColorData |
ScriptableObject that maps TypeColor enum values to Unity Materials. Used by buses and people to get the correct material for their assigned color. |
| Script | Description |
|---|---|
FLS |
BFS pathfinding utility (singleton). Provides FindShortestPathToBottom() which finds the shortest walkable path from a grid position to the bottom edge, used to route people toward buses. |
Item |
Generic utility component. Placeholder MonoBehaviour for items and auxiliary objects in the scene. |
DeveloperModeButton |
Toggles a developer settings panel on click. Auto-finds a child named DeveloperSettingsPanel if no reference is assigned in the inspector. |
DeveloperSettingsController |
Developer panel with buttons for level navigation (next, previous, reload, trigger win/lose), booster debugging (unlock all, refill all, reset popups), visual theme cycling, and ad testing (show/hide banner, show/request interstitial, show/request rewarded). |
| Script | Description |
|---|---|
LevelEditorWindow |
Unity Editor window (Tools > Bus Out Crowd Jam > Level Editor) for visually designing levels. Features a left panel with level list and a right panel with grid painter, box management, and car column configuration. |
LevelEditor |
Custom inspector for LevelData ScriptableObjects. Provides in-inspector grid visualization, box management with color-coded painting, and car column editing. |
LevelEditorHelper |
Editor-only static helper for level file I/O. Handles reading/writing JSON level files to disk, listing existing levels, and finding the highest level number. |
LevelGenerator |
Unity Editor window (Tools > Bus Out Crowd Jam > Auto Level Generator) with the LevelGenerator algorithm for batch-generating levels using region-growing grid partitioning, difficulty curves, and car capacity matching. |
BusOutCrowdJamWelcomePopup |
Welcome popup that appears on project open. Prompts the user to leave a review on the Asset Store and cross-promotes the HyperCasual Game Engine. Can be permanently dismissed. |
In the Unity menu bar, go to Tools > Bus Out Crowd Jam > Level Editor. This opens a dedicated Editor window — no need to enter Play mode.
| Mode | Left Click |
|---|---|
| None | No painting — click cells to inspect their contents |
| Box | Place a colored person at the clicked cell (adds to the selected box). Click again to toggle off. If a cell belongs to another box, it is moved to the selected box. |
| Erase | Remove whatever person/box is at the clicked cell. Empty boxes are automatically cleaned up. |
All levels are stored as individual JSON files in Assets/Bus Out Crowd Jam/Resources/Levels/ with the naming convention Level_1.json, Level_2.json, etc. They are loaded at runtime via Resources.LoadAll.
The Automatic Level Generator is an Editor tool that batch-generates playable puzzle levels procedurally. It uses region-growing grid partitioning with configurable difficulty curves to create varied, balanced levels.
In the Unity menu bar, go to Tools > Bus Out Crowd Jam > Auto Level Generator. This opens a settings window where you can configure all parameters before generating.
| Setting | Description |
|---|---|
| Levels to Generate | How many new level files to create. New levels are appended after existing ones (never overwrites). |
| Columns / Rows (Min & Max) | Range for randomizing the grid dimensions of each level. Default: 5–15. |
| Color Count (Min & Max) | Range for the number of distinct colors used per level. Default: 2–6. |
| Region Size (Min & Max) | Target number of cells per colored region. Controls how large each people group tends to be. Default: 6–45. |
| Bus Columns (Min & Max) | Range for the number of bus queue columns. Default: 2–4. |
| Cars Per Column (Min & Max) | Range for the number of buses in each queue column. Default: 2–4. |
| Car Capacity (Min & Max) | Range for bus passenger capacity. Inverted difficulty: early levels get large buses (easier), late levels get smaller buses (harder). Default: 6–20. |
| Parking Slots (Min & Max) | Range for the number of parking dock slots per level. Always at least one more than the bus column count. Default: 2–6. |
| VIP Slots (Min & Max) | Range for locked VIP parking slots. Only appear after the VIP Intro Level. Default: 0–2. |
| VIP Intro After Level | VIP slots only start appearing after this level number. Default: 20. |
| Booster Uses (Shuffle, Pick Any, VIP Dock) | Min/Max booster uses per level. Inverted difficulty: more uses on early levels, fewer on harder levels. |
Resources/Levels/The generator never overwrites existing level files. It always starts numbering from the next available index (e.g., if Level_500 exists, new levels start from Level_501). Use the "Delete ALL Levels" button if you want to start fresh.
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 |
|---|---|---|
| Shuffle | Randomly rearranges all buses across all queue columns using a smooth arc animation. Changes which bus is at the front of each line, creating new strategic options. | Tap the Shuffle button (Booster-Button-1). Consumes one use immediately. |
| Pick Any | Activates a special mode where the player can tap any bus in any queue position, not just the front bus. Non-tappable buses flash with a white pulse to indicate they are now selectable. The selected bus instantly teleports to the dock with a poof particle effect. | Tap the Pick Any button (Booster-Button-2) to toggle the mode on. Tap again to cancel without consuming a use. A use is consumed only when you actually pick a non-front bus. |
| VIP Dock | Unlocks one locked (VIP) parking slot, making it available for docking buses. Useful when all regular slots are occupied. | Tap the VIP Dock button (Booster-Button-3). Only active when there are locked docks remaining. |
Booster buttons are found in the GameHUD_Panel/BottomHolder in the scene UI. Each button has:
Bg) that shows/hides based on availabilityPowerUpCountText) showing remaining uses, or the unlock level if still lockedrgba(134, 191, 255)) when Pick Any mode is waiting for a target clickPress 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.
This project includes the RagendomAds monetization module for integrating AdMob ads (banners, interstitials, and rewarded videos). The ad system supports both real AdMob ads on device and a built-in Dummy ad provider for testing in the Unity Editor.
Full setup and configuration instructions for the ad system are provided in a separate documentation file located at:
That documentation covers AdMob app IDs, ad unit IDs, UMP/GDPR consent, test devices, and all monetization settings.
If you prefer a video walkthrough over reading documentation, watch the full ads setup tutorial here:
▶ Watch Ads Setup Tutorial on YouTube
The ad system consists of the following key components in the scene:
MonetizationInitModule component. It initializes the ad system on Awake using the assigned MonetizationSettings asset.Assets/Bus Out Crowd Jam/RagendomAds/Modules/Monetization/MonetizationSettings.asset. Contains all ad provider configuration, timing, and consent settings.Dummy provider for editor testing.| Ad Type | Description |
|---|---|
| Banner | A small ad strip displayed at the top or bottom of the screen. Show and hide at any time via Ragendom.AdsManager.ShowBanner() and HideBanner(). |
| Interstitial | A full-screen ad. Must be requested (loaded) first via RequestInterstitial(), then shown when ready via ShowInterstitial(). Supports cooldown timers and conditions. |
| Rewarded Video | A full-screen video ad that grants a reward on completion. Must be requested first via RequestRewardBasedVideo(), then shown via ShowRewardBasedVideo(). Always available regardless of no-ads purchases. |
By default, the ad system uses the Dummy provider, which displays test UI overlays in the Editor (a green "TEST BANNER" bar, dark "TEST INTERSTITIAL" overlay, and blue "TEST REWARDED VIDEO" overlay). This lets you verify the ad flow without needing a real device or AdMob account.
The Developer Settings Panel (accessible via the gear icon in-game) includes ad control buttons for testing: Show/Hide Banner, Show/Request Interstitial, and Show/Request Rewarded Video.
To add a new person/bus color:
LevelData.cs and add a new entry to the TypeColor enum:
LevelDataJson.cs and add the color to the BusCrowdColors.colors dictionary:
Art/Materials/Color/ with the desired colorColorData ScriptableObject in Datas/Colors/New colors are automatically available in the Level Editor, Auto Level Generator, and at runtime.
The grid layout is controlled by GridManager.cs. Key properties:
gapBetweenCells — Spacing between grid cells in world units (adjustable in the Inspector)pedestalPrefab — The ground pedestal placed under each personpedestalDefaultMaterial — Default material for empty pedestalshiddenMaterial / hiddenMaterial2 / hiddenMaterial3 — Materials for hidden/transition statesBus rendering is handled by the Car component. Each bus prefab includes:
ColorDataCarOutline shader loaded from Resources; outline meshes are created/destroyed dynamically by TapOutManagerPeople 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 run and standUp.
New boosters can be added by following the existing pattern in BoosterManager.cs:
HookUpExistingBoosters() following the HookUpBoosterButton() patternOnMyBoosterClicked())JsonLevelData and LevelData so it can be configured per levelUpdateBoosterUI() to handle the new booster's lock/unlock/count displayEach level is a JSON file with the following structure:
The boxes array defines colored people groups on the grid. Each box has a typeColor (integer matching the TypeColor enum) and a list of grid positions. The carColumns array defines bus queues, where each column contains a list of cars with amount (passenger capacity) and typeColor. Grid coordinates are zero-indexed with (0,0) at the top-left corner.
| Issue | Solution |
|---|---|
| No levels load / empty grid appears | Ensure JSON level files exist in Assets/Bus Out Crowd Jam/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. |
| Bus outline not showing | The outline effect requires the CarOutline.shader file in Resources/. If missing, the system falls back to searching for Custom/OutlineOnly. Ensure the shader is included in the build. |
| People don't walk to buses | Check that the GridManager dock transforms are properly configured and that the grid has a clear path from people positions to the bottom edge. The BFS pathfinder (FLS) requires walkable cells (value 0) in the grid. |
| 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. |
| 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. |
| VIP Dock booster does nothing | The VIP Dock booster only works when there are locked docks remaining. Ensure the level's vipSlots value is greater than 0 and that the parking slot count allows for locked docks. |
Resources/Levels/ folder regularlyIf you get stuck or have any issues, feel free to reach out to us at ragendom@gmail.com. We are happy to help!