Game Development · Unity · C#

3D CAR RACING GAME

Unity
C#
3D Racing Game
Solo Developer
Scroll to explore
Add your gameplay video here
YouTube embed or self-hosted .mp4
01

The Story

This started as a school project — but I wanted to build something I'd actually be proud to show people. So instead of a simple demo, I went all-in: a fully playable 3D car racing game, built from scratch in Unity using C#.

The goal was simple — give the player a fun, fast, and responsive racing experience. But building that required solving a lot of problems I hadn't dealt with before: realistic car physics, AI opponents that actually race intelligently, a track system with checkpoints, and a clean UI to tie it all together.

The challenge: Most Unity tutorials give you the basics. But making a game that actually feels good to play? That took a lot of iteration, testing, and going back to the drawing board.

Add a gameplay screenshot here
[replace with <img src="...">]
Fig 1 — Gameplay screenshot
02

How It's Built

I structured the game using an N-tier architecture with the MVC pattern — keeping the code clean, modular, and easy to extend. Here's how the layers break down:

PRESENTATION
What the player sees
HUD showing speed, lap count, timer, and health in real time
3D rendering of cars, tracks, and environments using Unity's engine
Keyboard, mouse, and game controller support for all input types
In-game menus and notifications (race start, finish, collisions)
APPLICATION
The game logic
Race rules: lap counting, timing, win/loss conditions
Multiplayer sync — keeping all player states in check
Event system handling collisions, power-up pickups, and race completion
Custom AI logic for opponent cars using pathfinding and steering behaviors
DATA
Storage & persistence
MongoDB for player data — scores, progress, car customizations, settings
JSON files for lightweight config — track layouts, car stats, AI parameters
Async read/write to avoid blocking the main game thread
Add a wide screenshot or architecture diagram here
Fig 2 — Game overview / track view
03

Tech Stack

Engine
Unity
Main game engine — handles rendering, physics, and the scene lifecycle.
Language
C#
All game logic written in C# — from car physics to AI behavior and UI updates.
Physics
Unity Physics
Built-in Unity physics engine, extended with custom car physics for realistic driving.
Networking
Photon PUN
Photon Unity Networking for multiplayer — syncing player states across the network.
Audio
FMOD
Advanced audio management — dynamic sound effects tied to speed and game events.
Database
MongoDB + JSON
MongoDB for player progress and scores. JSON for game config and settings files.
AI opponent / car physics screenshot
Fig 3
Fig 3 — AI car pathfinding in action

AI That Actually Races

One of the hardest parts of this project was making the AI opponents feel real. I built a custom AI Car class that inherits from the base Car class and adds its own pathfinding and steering logic.

The AI calculates its path around the track, adjusts its speed on corners, and responds to obstacles — all while staying competitive without feeling like it's cheating.

Pathfinding Steering Behaviors Custom AI Library State Machine Obstacle Avoidance
04

Class Design

I broke the game down into clean, focused classes. Each one handles one thing — making the code easier to debug, extend, and hand off.

Car
Base Class
Attributes
position Vector3
speed double
acceleration double
health int
Methods
Accelerate() void
Brake() void
Steer() void
CheckCollision() void
AICar
Extends Car
Attributes
path List<Vector>
aiState String
Methods
CalculatePath() void
Accelerate() override
Steer() override
GameController
Core
Attributes
level int
gameState String
Methods
Start() void
End() void
Update() void
StatsManager
Tracking
Attributes
currentScore int
highScore int
playerPoints int
Methods
AddPoints(int) void
ResetScore() void
UpdateHighScore() void
Track
Environment
Attributes
length double
width double
segments List<Segment>
Methods
GenerateTrack() void
UpdateTrack() void
PowerUp
Gameplay
Attributes
position Vector3
type String
effect String
Methods
ApplyEffect() void
RemoveEffect() void

Testing & Code Quality

I set up a full testing pipeline with NUnit for unit tests and regular playtesting sessions to catch bugs that only show up when you're actually playing.

Version control was managed with Git — feature branches for new functionality, a develop branch for integration, and the main branch kept clean for releases.

I also set up a CI/CD pipeline for automated testing on every push, which saved a lot of time catching regressions early.

NUnit Tests Git Branching CI/CD Pipeline Playtesting
Add a screenshot of your Unity editor
or testing results here
Fig 4
Fig 4 — Unity editor / test results
05

Project Timeline

Weeks 7–8
Pre-Production
Concept, planning, and initial design. Finalized the architecture, chose the tech stack, and sketched out the game mechanics.
Week 8 — Milestone
Core Mechanics Done
Car movement, basic physics, and the track system were all working. First time I could actually drive around the map.
Weeks 8–10
Production
Built the AI opponents, added power-ups and obstacles, integrated MongoDB and JSON data storage, and wired up the full UI.
Week 10 — Milestone
First Playable Prototype
A complete race with AI opponents, working HUD, lap counting, and a win condition. Rough around the edges, but fun to play.
Weeks 11–12
Testing & Polish
Playtesting sessions, bug fixes, tuning the AI difficulty, and polishing the UI. NUnit tests added for core game systems.
Week 13 — Final
Release Ready
Final version completed with documentation, clean codebase, and a CI/CD pipeline in place.