Hexa Away Puzzle 3D

A Hexagonal Slide-to-Hole 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 hexagonal slide-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

Hexa Away Puzzle 3D is a hexagonal slide-to-hole puzzle game where players tap colored hex stacks to launch them along their arrow direction. If the path is clear, the stack flies off the board; if another stack is in the way, the tap bumps and still costs a move. Clear every stack within the level's move budget to win. The game features a procedural hex mesh, a built-in level editor, an automatic level generator with a built-in solvability validator, and a booster system.

Tap-to-Slide Puzzles

Intuitive one-tap controls — tap any reachable hex stack to launch it along its arrow direction. Stacks bump, rotate, or clear depending on what's ahead.

Level Editor

Full Unity Editor window for designing hex levels with a visual grid painter — place grounds, holes, and colored stacks on a double-offset hex grid with color and direction pickers.

Auto Level Generator

Batch-generate hundreds of playable hex levels with configurable difficulty curves, level width and height (up to 24 hex-rows tall), color counts, island spread, and per-level booster budgets.

Booster System

Three in-game boosters — Bomb (clears a stack plus its 6 neighbours), +Moves (adds 5 moves to the run), and Hint (pulse-highlights a launchable stack) — with first-use tutorial popups and per-level unlocks.

500 Levels Included

Ships with 500 pre-generated levels on a progressive difficulty curve, every one validated solvable by the built-in greedy solver before being written to disk. Generate more at any time with the auto generator.

Getting Started

Requirements

Installation

  1. Import the Hexa Away Puzzle 3D 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/Hexa Away Puzzle 3D/Scenes/GameNew.unity
  4. Press Play to test the first level

Quick Test

Once in Play mode, tap any hex stack whose arrow direction is unblocked — it flies off the board in that direction and you score a clearance. Tap a blocked stack and it bumps, consuming a move but not clearing. Clear every stack within the move budget to win and the next level loads automatically. A wrong tap still costs a move, so the player can genuinely lose.

Folder Structure

Hexa Away Puzzle 3D/ │ ├── Art/ — Shared materials and textures (one .mat per palette colour) │ ├── Audio/ — All sound effects (.wav): Tap, Blocked, LevelClear, LevelFail, Booster-activate │ ├── Documentation/ — This documentation file │ ├── Editor/ — Editor-only scripts (namespace: HypercasualGameEngine.EditorTools) │ ├── LevelEditorWindow.cs — Visual hex-grid level designer │ ├── LevelGenerator.cs — Auto level generator core (solvability-validated) │ ├── LevelGeneratorWindow.cs — Auto generator UI window │ └── HexaAwayPuzzle3DWelcomePopup.cs — Welcome popup on project open │ ├── PostProcessing/ │ └── HC-PostProcessing-Volume.asset — Shared HyperCasual URP VolumeProfile (Bloom, Tonemapping, Color Adjustments, Vignette). Referenced by the scene's Global Volume and both URP RPAssets. │ ├── Prefabs/ — All UI prefabs (HUD, lose/win, dev panel, booster popup) │ ├── GameHUD_Panel.prefab │ ├── LoseWinPanel.prefab — Container that hosts LoseWinPanelManager; LevelClearedPanel + GameOverPanel are dropped under it in the scene │ ├── GameOverPanel.prefab — Lose UI (skull + FAILED + Retry button). No level-number text by design. │ ├── LevelClearedPanel.prefab — Win UI (trophy + COMPLETED + CurrentLevelText "LEVEL N" + Continue button) │ ├── Popup_Powerup_Picker.prefab │ ├── DeveloperModeButton.prefab │ └── Global/ — Shared UI prefabs │ ├── Resources/ │ └── Levels/ — 500 level JSON files (Level_1.json ... Level_500.json) │ ├── Scenes/ │ └── GameNew.unity — Main game scene (single playable scene) │ └── Scripts/ — All runtime scripts (namespace: HypercasualGameEngine) ├── HexaAwayGameManager.cs — Top-level orchestrator, arrow-key nav, win/lose choke point ├── HexLevelManager.cs — Gameplay: tile spawn, tap input, move counting, power-ups ├── HexStack.cs — Visual stack container and tile management ├── HexTile.cs — Individual hex tile (top + side colours, direction arrow) ├── HexTileAnimator.cs — Tumble, slide, and fly-off animation coroutines ├── HexCoordinates.cs — Double-offset hex math, HexDirection enum, neighbour offsets ├── HexMeshGenerator.cs — Procedural flat-topped hex mesh builder ├── LevelManager.cs — Static JSON level loader, PlayerPrefs progression ├── LevelData.cs — Serializable stack / hole / booster-count container ├── BoosterManager.cs — 3-booster state machine, level-gated, with first-use popups ├── SoundManager.cs — Singleton audio facade ├── LoseWinPanelManager.cs — Win / lose UI + auto-advance ├── GameHUD.cs — Level label and moves counter binding ├── DeveloperModeButton.cs — Dev panel toggle ├── DeveloperSettingsController.cs — Dev panel controls (level navigation, booster debug, ads) └── CameraSwitcher.cs — Multi-camera helper (engine bundle leftover) Settings/ — URP render pipeline assets TextMesh Pro/ — TextMeshPro essentials

Gameplay

Core Mechanics

Each level is a hex-grid of colored stacks and holes laid out on a flat-topped, double-offset hex coordinate system. Every stack points in one of six hex directions and launches along that arrow when tapped.

Hex Directions

All stacks use one of six hex directions in flat-topped double-height-offset coordinates. The direction enum value is serialized directly into the JSON level files:

Enum Value Cell Offset (Δcol, Δrow)
Up0(0, -2)
Down1(0, +2)
UpperLeft2(-1, -1)
UpperRight3(+1, -1)
LowerLeft4(-1, +1)
LowerRight5(+1, +1)

Stack Colors

The base palette ships with seven configurable colours. The auto generator picks a 3–7-colour subset per level based on difficulty.

Color Key Color Reference Hex
red Red#FF4757
orange Orange#FFA502
green Green#7BED9F
gray Gray#A4B0BE
blue Blue#48DBFB
purple Purple#BC8CFF
black Black#2D2D2D

The palette key is the lowercase string written into the JSON. Materials in Art/Materials/ are matched by file name (red.mat, orange.mat, …).

Win & Lose Conditions

Animations

Each stack has three animation states: idle (static, with the direction arrow visible on top), launch (tumble + slide along the hex axis when the path is clear), and bump (small kick-back when the path is blocked). Cleared stacks play a tile-by-tile fall-off cascade. The Bomb booster adds an explosion burst with an outward shockwave on the targeted stack and its 6 neighbours.

Scripts Reference

Runtime scripts use the HypercasualGameEngine namespace. Editor scripts use the HypercasualGameEngine.EditorTools namespace. The engine namespace is shared across every game in the bundle — do not change it, or save files written by other games will fail to load.

Core Scripts

Script Description
HexaAwayGameManager Top-level orchestrator. Decorated [DefaultExecutionOrder(-100)] so it runs before every other script. Tracks the game state enum (Playing / Won / Lost), creates missing scene singletons (EventSystem, SoundManager, BoosterManager) via FindFirstObjectByType, handles arrow-key level navigation and the U-key booster debug shortcut, and is the single call site for TriggerWin / TriggerLose.
HexLevelManager Gameplay core. Reads the current LevelData from LevelManager.GetCurrentLevel() and spawns one HexStack per LevelStackData entry. Handles tap-to-launch raycasts, pathfinds along arrow directions, counts moves, and runs the bomb / hint power-ups. Never falls back to an Inspector-assigned demo level.
HexStack Container for a visual stack of hex tiles at a grid coordinate. Holds the direction, the tile list, and the logic to mark the new top tile after each removal. Setup() takes the coords, direction, top + side material pair, stack size, and hex radius.
HexTile Individual hex disc inside a stack. Owns the top + side material assignment, the direction arrow renderer (top tile only), and the bomb-explode coroutine.
HexTileAnimator All tile-level animation coroutines: tumble, slide along a hex axis, fly-off, and the staggered top-to-bottom fall-off cascade when a stack is cleared.
HexCoordinates Double-offset hex math. Provides ToWorldPosition(hexRadius) on the XZ plane, the six neighbour offsets, and the HexDirection enum + its HexDirectionHelper with GetOffset, GetWorldDirection, and GetTumbleAxis.
HexMeshGenerator Procedurally builds the flat-topped hex mesh with separate top and side sub-meshes so each can take its own material.
LevelManager Static class that loads Level_N.json files from Resources/Levels/ at runtime via Resources.Load<TextAsset>("Levels/Level_" + i) in a strict-sequential loop, tracks the current level index via the HexaAwayPuzzle3D_CurrentLevel PlayerPrefs key, and provides editor-only save / delete APIs that read from the absolute path under Assets/Hexa Away Puzzle 3D/Resources/Levels/.
BoosterManager Three-booster state machine. Owns the booster counts (single source of truth — gameplay scripts never store counts of their own), level-gated unlock (booster N unlocks at level N−1), first-use tutorial popup keyed in PlayerPrefs, and the four-state HUD button UI (Locked / Usable / Depleted / Active). Exposes OnBombActivated / OnMovesBoosterUsed / OnHintActivated for per-game wiring.
SoundManager Singleton audio facade. Single AudioSource, single masterVolume slider. One Play<Event>() method per game event — PlayTap(), PlayBlocked(), PlayLevelClear(), PlayLevelFail(), PlayBoosterActivate(). No background music by design.
LevelData Serializable POCO: totalMoves, bombCount, movesBoosterCount, hintBoosterCount, stackSize, plus lists of LevelStackData (col, row, colorName, direction) and LevelHoleData (col, row).
LoseWinPanelManager Win / lose overlay prefab controller. LoadNextLevel calls LevelManager.AdvanceLevel() before reloading the scene so progression actually advances (the template placeholder-bug is patched). ShowWin() writes "LEVEL N" into winLevelText before activating LevelClearedPanel; ShowLose() intentionally does NOT populate a level-number field (GameOverPanel has no such TMP by design). Self-wires at Start() via AutoWireReferences() — searches first for direct children WinPanel / LosePanel, then scene-wide for LevelClearedPanel / GameOverPanel, and recursively for ButtonRetry / ButtonContinue / CurrentLevelText. Also exposes an Auto-Wire References context menu item for in-editor preview. Does NOT modify LocalScale on show — respects whatever design-time scale the panels have in the scene.
GameHUD Binds the existing HUD prefab's CurrentLevelText and moves counter to game state. Lives on the GameHUD_Panel prefab root — does not create its own Canvas at runtime (single-canvas invariant: the template canvas is the only canvas in the scene).

Utility Scripts

Script Description
DeveloperModeButton Toggles a developer settings panel on click. Auto-finds a child literally 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), and ad testing (show / hide banner, show / request interstitial, show / request rewarded). Shift+combo hotkeys live here; plain-arrow / plain-U handlers live on HexaAwayGameManager (so they fire even when the dev panel GameObject is inactive).
CameraSwitcher Multi-camera helper from the engine bundle. Unused in the single-scene build but kept for reference if you later add an in-app launcher across multiple games.

Editor Scripts

Script Description
LevelEditorWindow Unity Editor window (Tools > Hexa Away Puzzle 3D > Level Editor) for visually designing hex levels. Two-pane layout: left panel with level list and add / duplicate / reorder / delete / save-all / reload actions; right panel with hex-grid painter, paint-mode toolbar, and per-level fields (move budget, booster counts, stack size, palette).
LevelGenerator Auto level generator core. Owns the four-stage solvability loop (preferred → solvable-only → difficulty-eased → minimal fallback), the difficulty-curve interpolation, the polar island seeding, the connected-land BFS growth, the hole-vs-stack partitioning with interior-bias, and the greedy fire-anything-launchable solver used to validate every candidate before it's written to disk.
LevelGeneratorWindow Unity Editor window (Tools > Hexa Away Puzzle 3D > Auto Level Generator) that exposes the LevelGenSettings struct as a min/max pair UI and runs the generator with a cancellable progress bar.
HexaAwayPuzzle3DWelcomePopup Welcome popup that auto-opens once per editor session via [InitializeOnLoadMethod]. Two CTA buttons (leave a review on the Asset Store, get the HyperCasual Game Engine bundle) plus a "Do not show this popup again" checkbox. Permanently dismissable via EditorPrefs. Not exposed in the menu.

Level Editor

Opening the Level Editor

In the Unity menu bar, go to Tools > Hexa Away Puzzle 3D > Level Editor. This opens a dedicated Editor window — no need to enter Play mode.

Features

Paint Modes

Mode Left Click
Ground Place a base ground tile at the clicked cell. Stacks need a ground beneath them.
Hole Mark the clicked cell as a hole — a gap in the land that interrupts a launch path.
Stack Place a colored stack at the clicked cell using the currently-selected colour and direction. Click again with a different colour / direction to overwrite.
Erase Remove whatever ground / hole / stack is at the clicked cell.

Level Storage

All levels are stored as individual JSON files in Assets/Hexa Away Puzzle 3D/Resources/Levels/ with the naming convention Level_1.json, Level_2.json, …, Level_N.json. They are loaded at runtime via a strict-sequential Resources.Load<TextAsset>("Levels/Level_" + i) loop — a gap in the numbering will truncate the playable set.

Automatic Level Generator

The Automatic Level Generator is an Editor tool that batch-generates playable hex puzzles. Every candidate is run through the built-in greedy solver before being written to disk — nothing unsolvable is ever saved, even as a last-resort fallback.

Opening the Tool

In the Unity menu bar, go to Tools > Hexa Away Puzzle 3D > Auto Level Generator. This opens a settings window where you can configure all parameters as min/max pairs before generating. The left value is the difficulty-0 (easy) end; the right value is the difficulty-1 (hard) end.

Settings

Setting Description
Levels To Generate How many new level files to create. New levels are appended after existing ones (the generator never overwrites). Default: 500.
Spread Radius (Min & Max) Polar distance that island seeds spawn from the grid centre. Larger spread = wider multi-island layouts. Default: 3 → 8.
Land Count (islands) Number of disconnected land pieces per level. Typically 1 at easy, 2–3 at hard. Default: 1 → 3.
Stacks / Level Total stack count per level — the dominant difficulty driver. Default: 6 → 32.
Holes / Level Number of hole cells drilled into the land. Biased toward interior cells so harder levels sometimes get donut-shaped islands. Default: 1 → 8.
Stack Size Visual height of each stack in tiles. Cosmetic only — does not affect gameplay. Default: 3 → 6.
Error Margin Extra moves above the strict minimum, expressed as a multiplier. moves = stacks + round(stacks × errorMargin). Easy = 1.00 (lots of room); hard = 0.15 (tight). Note: invalid taps cost a move too, so this is genuine headroom.
Colors In Play Subset of the 7-colour palette used per level. Default: 3 → 7.
Bomb / +Moves / Hint Booster Counts Min / max booster counts per level. Inverted difficulty: more boosters on early levels, fewer on harder ones.
Use Fixed Seed When enabled, runs the generator with a deterministic seed so the same settings always produce the same level set. Useful for reproducible regeneration.

How It Works

  1. Configure settings — adjust all min / max parameters in the Editor window
  2. Click "Generate Levels" — the tool detects existing files and appends new ones (e.g. if Level_500 exists, new levels start from Level_501)
  3. For each level, the generator:
    • Interpolates every setting against the difficulty curve (concave ramp, reaches max difficulty by level ~12 regardless of total batch size)
    • Adds ±7% jitter on the curve so two adjacent levels are never identical even at the same difficulty bucket
    • Seeds 1–3 islands on a polar layout around the grid centre
    • Grows each island via random-walk BFS until the target cell count is reached
    • Partitions land cells into stacks vs. holes (interior-biased so harder levels get donut shapes)
    • Picks a direction for each stack, preferring blocked paths so the player has to plan the clearing order (block-preference scales 30% → 85% with difficulty)
    • Runs the greedy fire-anything-launchable solver on the candidate; if unsolvable, retries with progressively eased difficulty
    • Falls back to a guaranteed-solvable 3-stack minimum if every other stage fails (should never happen in normal operation)
    • Exports the validated level as a JSON file to Resources/Levels/

Grid Envelope

The generator clips every level to a hard 11 hex-columns × 24 hex-rows envelope so the land stays within the camera frustum. Stacks and holes are never placed outside this box even if the requested radius would push them out. The 24-row vertical cap means later levels can stretch up and down on screen far beyond what the early-game examples show.

Non-Destructive

The generator never overwrites existing level files. It always starts numbering from the next available index. Use the red "Delete ALL Levels" button at the bottom of the window if you want to wipe the folder and start fresh. Every save also goes through the solvability validator — the generator will skip a slot rather than write a broken level.

Boosters

The game includes three booster abilities that players can activate during gameplay. Each booster has a configurable starting count per level (set in the level JSON data) and a one-time tutorial popup on first use, dismissed permanently after the player closes it.

Booster Effect Activation
Bomb Targeting toggle. Tap a stack on the board to clear it plus its six hex neighbours, regardless of arrow direction. Useful when a stack is unreachable through normal launches. Tap the Bomb button (Booster-Button-1) to enter targeting mode. Tap a stack to fire. Tap the button again to cancel without consuming a use.
+Moves Adds 5 moves to the current level's move budget. Instant — no targeting step. Tap the +Moves button (Booster-Button-2). Consumes one use immediately and updates the moves counter on the HUD.
Hint Pulse-flashes one stack on the board that can be cleared right now (its arrow path is unblocked). The flash fades after a couple of seconds; pressing again finds another candidate. Tap the Hint button (Booster-Button-3). Consumes one use immediately. Does nothing if no stack is currently launchable.

Booster Buttons

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

Source of Truth

Booster counts live on BoosterManager, never on the gameplay script. HexLevelManager stores only the active power-up mode (e.g. "Bomb is in targeting mode") and asks BoosterManager.Instance.ConsumeBomb() when the effect actually fires. This avoids drift between the HUD count label and the underlying state — a class of bugs where the HUD says "1 bomb left" but a click silently does nothing.

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 live on HexaAwayGameManager.Update so they fire even when the dev panel GameObject is inactive.

Customization Guide

Adding New Colors

To add a new stack colour:

  1. Open LevelGenerator.cs and append the colour key to the static Palette array:
    private static readonly string[] Palette = { "red", "orange", "green", "gray", "blue", "purple", "black", // Add your custom color: "pink" };
  2. Create a Material in Art/Materials/ with the file name matching the new key (e.g. pink.mat) so it's resolved at runtime by name lookup.
  3. Update the editor's color-picker swatch list in LevelEditorWindow if you want to paint the new colour by hand.

New colours are automatically eligible for the auto generator's per-level subset (Colors In Play max).

Adjusting Hex Visuals

The hex layout is controlled by HexLevelManager.cs. Key properties:

Modifying Stack Visuals

Stack rendering is handled by the HexStack + HexTile pair:

Adjusting Difficulty

Edit the constants at the top of LevelGenerator.cs:

Adding New Boosters

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

  1. Add a count int field to LevelData (e.g. shuffleBoosterCount) so it can be configured per level.
  2. Add booster state fields (use count, active flag, UI references) to BoosterManager.
  3. Wire up the button in HookUpExistingBoosters() following the existing pattern (find the child by literal string match — Booster-Button-N names are load-bearing, do not rename).
  4. Implement the booster effect in a click handler method, calling out to HexLevelManager if it needs game-state access.
  5. Update UpdateBoosterUI() to handle the new booster's lock / unlock / count display.

JSON Level Format

Each level is a JSON file with the following structure:

{ "totalMoves": 14, "bombCount": 1, "movesBoosterCount": 2, "hintBoosterCount": 2, "stackSize": 4, "stacks": [ { "col": 12, "row": 12, "colorName": "red", "direction": 0 // 0=Up, 1=Down, 2=UpperLeft, 3=UpperRight, 4=LowerLeft, 5=LowerRight }, { "col": 13, "row": 11, "colorName": "blue", "direction": 4 } ], "holes": [ { "col": 12, "row": 14 } ] }

Coordinates use double-height hex offset with the centre at (12, 12). Valid cells satisfy parity: (col + row) must be even (or odd, depending on the starting parity of the level — mixing parities will produce gaps in the visible board). The colorName string must match a key in LevelGenerator.Palette and a .mat file in Art/Materials/.

Support

Common Issues

Issue Solution
No levels load / empty board appears Ensure JSON level files exist in Assets/Hexa Away Puzzle 3D/Resources/Levels/ with the naming convention Level_1.json, Level_2.json, …. Use the Auto Level Generator to create levels if the folder is empty. The loader is strictly sequential — a missing index truncates the playable set.
Pink / magenta materials on stacks or grounds 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.
Level 1 plays, but the Win screen reloads Level 1 instead of advancing Verify LoseWinPanelManager.LoadNextLevel() calls LevelManager.AdvanceLevel() before reloading the scene. This is the production fix — the engine template's placeholder version only reloaded the scene without advancing the index.
Booster buttons stay dark / disabled Check you're past the unlock level — +Moves needs level 2, Hint needs level 3 by default. Press U to force-unlock and refill all boosters for testing.
No sound Open the SoundManager GameObject in GameNew.unity and verify each clip field has a .wav assigned from Assets/Hexa Away Puzzle 3D/Audio/. The masterVolume slider must also be above 0.
UI tap doesn't register Verify there is exactly one EventSystem in the scene. HexaAwayGameManager.SetupGame creates one automatically if missing — if you removed that code path, restore it. Also: every overlay panel must carry its own Canvas with overrideSorting = true + a GraphicRaycaster, otherwise raycasts fall through to the board.
Auto generator produces "skipped" warnings This means the multi-stage solvability loop failed to produce a solvable level for that slot. Open the console — the warning lists how many attempts were made. Try widening Error Margin or lowering Stacks / Level at the hard end of the curve.
Generated levels render off-screen at the top or bottom The hard envelope is 11 columns × 24 rows. If you raised MaxRowSpan beyond 24 in LevelGenerator.cs, the camera frustum / orthographic size also needs to grow to match the taller grid.

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!