A 2D puzzle-platformer built in Unity that demonstrates core artificial intelligence algorithms applied to game development. The game features an AI-powered companion that uses A* pathfinding to navigate complex grid-based environments alongside the player across 10 handcrafted levels.
This project was built as a hands-on exploration of AI techniques in game development specifically how classical search algorithms translate into real-time, interactive game behavior. The companion character uses a custom-built A* implementation (not Unity's NavMesh) to find optimal paths through tile-based levels, avoid obstacles, and respond to player input in real time.
The core AI system is a from-scratch A* search algorithm built entirely in C# without Unity's built-in navigation tools:
- Grid Generation -
PopulateGrid.csandAStarGrid.csdynamically build a spatial grid from Unity Tilemaps at runtime, scanning for obstacle colliders and marking each cell as traversable or blocked - Manhattan Distance Heuristic -
GridBlocks.csstores f, g, and h scores per node; the heuristic uses Manhattan distance (|row_diff| + |col_diff|) for optimal 4-directional movement - Open/Closed List Management - Custom sorted linked list
(
List.cs) maintains the open frontier, sorted by f-score for efficient node selection - Path Reconstruction - Parent pointer traversal reconstructs the optimal path from goal back to start after search completes
The companion has three distinct behavioral modes:
| Mode | Trigger | Behavior |
|---|---|---|
| Follow | Default / Tab key |
Moves toward player using direct translation |
| Pathfind | Left mouse click | Runs A* to clicked world position, executes path |
| Land | Left Ctrl |
Toggles gravity companion drops and interacts with physics |
The grid is populated at scene start by scanning every cell with
Physics2D.OverlapBox, classifying cells as obstacles if they
contain tagged colliders (Companion Avoid) or Tilemap tiles.
This makes the pathfinding automatically adapt to any level layout
without manual configuration.
- Player - 2D platformer movement with double jump
- Companion - AI-driven ally that navigates to waypoints
- Puzzles - Keys, locks, buttons, pressure plates, dual locks, and reveal flags create multi-step puzzle sequences
- Hazards - Spike balls with automated movement patterns and reset behaviors
- Collectibles - Coins scattered across levels
- 10 Levels - Progressively complex environments that challenge both player platforming skills and companion pathfinding
| Layer | Technology |
|---|---|
| Engine | Unity (URP - Universal Render Pipeline) |
| Language | C# |
| AI | Custom A* pathfinding - no NavMesh |
| Physics | Unity Physics2D - OverlapBox, OverlapCircle |
| Rendering | Unity 2D URP Renderer |
| Grid | Unity Tilemap + custom spatial grid |
Assets/
├── Scripts/
│ ├── AStarGrid.cs # Grid data structure + neighbor lookup
│ ├── GridBlocks.cs # Node class - x, y, f/g/h scores, parent
│ ├── List.cs # Custom sorted linked list for open/closed
│ ├── PopulateGrid.cs # Runtime grid population from Tilemap
│ ├── companionMovement.cs # A* pathfinding + companion AI behavior
│ ├── playerMovement.cs # Player movement + double jump
│ ├── spikeBallSetMove.cs # Hazard AI - automated spike movement
│ ├── coinCollect.cs # Collectible system
│ ├── keyCollect.cs # Key pickup logic
│ ├── unlock.cs # Single lock interaction
│ ├── dualLock.cs # Dual lock puzzle mechanic
│ ├── pressButton.cs # Button trigger system
│ ├── revealFlag.cs # Hidden object reveal mechanic
│ └── levelManager.cs # Level state management
├── Scenes/
│ ├── MainMenu.unity
│ ├── LevelSelect.unity
│ ├── Level1 – Level10.unity
│ └── Credits.unity
└── Settings/ # URP renderer configuration
- Clone the repository
- Open in Unity 2022.3+
- Open
Assets/Scenes/MainMenu.unity - Press Play in the Unity Editor
| Input | Action |
|---|---|
A / D or Arrow Keys |
Move player left/right |
Space |
Jump (press twice for double jump) |
Left Click |
Send companion to clicked position |
Left Ctrl |
Toggle companion gravity (land/float) |
Tab |
Return companion to follow mode |
1. Build spatial grid from Tilemap at scene start
2. Mark obstacle cells via Physics2D.OverlapBox scan
3. On left click:
a. Set start block = companion's current grid cell
b. Set goal block = closest grid cell to click position
c. Run A* with Manhattan heuristic
d. Reconstruct path via parent pointers
e. Execute path via Vector3.MoveTowards per frame
The implementation uses 4-directional movement (up, down, left, right) diagonal movement is noted as a future enhancement in the codebase comments.
- Custom A over NavMesh* - Built from scratch to demonstrate understanding of the algorithm rather than using Unity's built-in navigation system
- Runtime grid generation - Grid populates dynamically from Tilemap data, making the system level-agnostic
- Sorted open list - Custom linked list sorted by f-score ensures the lowest-cost node is always selected first
- Obstacle tagging - Uses Unity's tag system (
Companion Avoid) to cleanly separate pathfinding concerns from game logic