This game prototype is a first-person shooter built in Unity, featuring core mechanics such as weapon switching, shooting, zooming, and interacting with pickups like ammo and new weapons. The player navigates an environment, combats enemy robots and turrets, and manages health and ammunition. The game includes UI elements for ammo and health, a win condition when all enemies are defeated, and a game-over state when the player’s health reaches zero.
Mechanically, the game supports both automatic and semi-automatic weapons, zoom functionality for precision aiming, and a responsive shooting system with visual and physical feedback (muzzle flash, camera shake, hit effects). Enemies include AI-driven robots that chase the player and turrets that fire projectiles. Pickups allow the player to replenish ammo or switch weapons, and the environment dynamically spawns enemies through gates. The design emphasizes fast-paced action, resource management, and skillful shooting.
Technically, the project demonstrates key Unity and C# concepts: ScriptableObjects
for weapon data, MonoBehaviour
scripting for player and enemy behaviors, coroutines for timed actions, and component-based architecture for modularity. The codebase covers collision handling, UI updates, camera control, and event-driven gameplay. By developing this prototype, one gains practical experience in Unity’s scripting API, game loop management, object pooling, and the implementation of common FPS mechanics, providing a solid foundation for more advanced game development.
[https://drive.google.com/file/d/1YNY7Q9GYboDQhJRvdjVS5yhh-AfnYJlH/view?usp=drive_link](https://drive.google.com/file/d/1YNY7Q9GYboDQhJRvdjVS5yhh-AfnYJlH/view?usp=drive_link)
Description:
Allows the player to switch between different weapons, each defined by a ScriptableObject
. When a new weapon is picked up, the current weapon GameObject
is destroyed and replaced with the new one, and ammo is reset.
public void SwitchWeapon(WeaponSO weaponSO)
{
if (currentWeapon)
{
Destroy(currentWeapon.gameObject);
}
Weapon newWeapon = Instantiate(weaponSO.weaponPrefab, transform).GetComponent<Weapon>();
currentWeapon = newWeapon;
this.currentWeaponSO = weaponSO;
AdjustAmmo(currentWeaponSO.MagazineSize);
}
flowchart TD
A[Pickup Weapon] --> B{Has Current Weapon?}
B -- Yes --> C[Destroy Current Weapon]
B -- No --> D
C --> D[Instantiate New Weapon]
D --> E[Set Current WeaponSO]
E --> F[Reset Ammo]
Description:
Handles player shooting input, firing the weapon if enough time has passed and ammo is available. Plays shooting animation, reduces ammo, and supports both automatic and semi-automatic weapons.
void HandleShoot()
{
timeSinceLastShot += Time.deltaTime;
if (!starterAssetsInputs.shoot) return;
if (timeSinceLastShot >= currentWeaponSO.FireRate && currentAmmo > 0)
{
currentWeapon.Shoot(currentWeaponSO);
animator.Play(SHOOT_STRING, 0, 0f);
timeSinceLastShot = 0f;
AdjustAmmo(-1);
}
if (!currentWeaponSO.isAutomatic)
{
starterAssetsInputs.ShootInput(false);
}
}
flowchart TD
A[Player Presses Shoot] --> B{Can Shoot?}
B -- Yes --> C[Shoot Weapon]
C --> D[Play Animation]
D --> E[Reduce Ammo]
B -- No --> F[Wait]
C --> G{Weapon is Semi-Auto?}
G -- Yes --> H[Reset Shoot Input]
Description: