All Case Studies

Stealth Action Top-Down Shooter

December, 2023

A stealth-action top-down shooter inspired by Metal Gear Solid: VR Missions, featuring ten levels, dynamic AI, diverse weapons, and tactical combat. Players complete objectives like evading detection, neutralizing enemies, and unlocking paths using strategic gameplay.

Introduction

  • Overview: Stealth Action Top-Down Shooter is a stealth-driven, top-down shooter inspired by Metal Gear Solid: VR Missions (1999). Across ten levels, players engage in various objectives, employing a blend of weapons and tactical maneuvers to outsmart or eliminate dynamic AI enemies. Each level introduces fresh challenges, encouraging players to strategically use the environment and weaponry to evade detection or execute precise attacks.
  • Motivation: Inspired by one of my favorite classic stealth games, I aimed to create a focused, feature-complete project that highlights advanced AI behaviors, modular weapon systems, and structured game development. This project pushed me to build a fully functional game with scalable systems and responsive AI mechanics, offering both stealth and action elements that integrate in a polished player experience.

Key Features

  • Player State System: The player operates in idle, grounded, falling, and dead states, with each state unlocking specific interactions. The player can:
    • Use Weapons: Pick up, drop, reload, and fire.
    • Engage in Melee Combat: Knock enemies unconscious by punching or through aerial takedowns.
    • Precise Control: A mouse-controlled crosshair allows for accurate aiming.
  • Simple Inventory: Players can carry one weapon and a keycard at a time, balancing equipment management and strategic decision-making.
  • Objective Tracking System: Levels have distinct objectives, including reaching goals undetected, defeating all enemies, and collecting keycards to unlock paths. Progress is tracked in-game and saved between sessions.
  • Advanced Enemy AI: Enemy AI is the core feature of this game, showcasing complex behaviors:
    • Behavioral States: Enemies cycle through idle, patrol, chase, attack, investigate, and call-for-backup states.
    • Sensory Systems: AI has hearing and vision capabilities; sight triggers pursuit, while sound alerts nearby enemies.
    • Backup Calls: Enemies who spot the player can call for backup, alerting others. However, if an enemy is neutralized mid-call, the backup is canceled.
    • Interaction with Downed Allies: Enemies will detect incapacitated allies (either dead or unconscious) and attempt to revive those unconscious. They display contextual emotional cues (e.g., murmuring or screaming) when reacting to incapacitated allies, depending on whether the ally is unconscious or dead.
    • Responsive Combat: When in attack mode, enemies shoot the player, and if they lose sight, they pursue in the last-seen direction for a limited time before returning to patrol. NavMesh-based pathfinding helps them navigate the environment intelligently.
  • Weapon Systems with Sound Emission: Players can wield a range of weapons:
    • Types: Melee, semi-auto pistol, full-auto rifle, and rocket launcher with explosive projectiles.
    • Silencers: Pistols and rifles can have silencers, lowering sound emissions to avoid alerting enemies. Unsilenced shots are moderately audible, while explosions are heard across the level.
    • Sound Emission System: Noise levels for each weapon type dynamically influence the enemy’s detection radius.
  • Sequential Level Unlocking: Completing each level unlocks the next, with progress automatically saved between sessions.
  • UI & HUD: The UI is minimal but functional, focusing on clarity:
    • Menus: Main menu, level selection, and HUD display key information like objectives, current weapon and ammo, and health bars for the player and enemies.
    • Enemy Status Indicators: Icons like question marks (suspicious) and radial progress bars (backup call, spotting progress, unconscious timer) provide feedback on enemy states.
    • In-Game Prompts and Feedback: On-screen cues guide player actions (e.g., pickup prompts), while game over, level completion, and pause menus manage navigation.

Key Challenges & Solutions

1. Modular State Machines for Player and Enemy

  • Challenge: Complex state-based logic for player and enemy behaviors (e.g., idle, patrol, attack, chase) required clear separation of states and transitions to prevent code entanglement.
  • Solution: Built finite state machines using the state pattern, encapsulating states into individual classes. Separate transition classes, managed by a central transition manager, handled conditions and state changes. This modular approach streamlined debugging, enabled rapid state addition, and promoted flexible, reusable transitions.

2. CharacterController with NavMesh Sampling

  • Challenge: Allow ledge-dropping while preventing the player from falling off the level bounds, overcoming Unity’s NavMeshAgent limitations.
  • Solution: Integrated Unity’s CharacterController for free movement, augmented with NavMesh sampling to restrict out-of-bounds positions. Movement logic verifies if the destination, including downward direction, remains within the NavMesh, enabling controlled ledge-drops while maintaining valid boundaries.

3. Refining Enemy Attack Behavior

  • Challenge: Enemies exhibited unrealistic behavior during attacks, such as overshooting, getting too close, or losing sight at certain angles, reducing realism.
  • Solution: Programmed a system to calculate attack positions based on player visibility and safe distance. Enemies move to a calculated safe position when the player is visible with a clear line of fire. Alternative positions around the player are evaluated for validity and accessibility using NavMesh checks and path simplicity, ensuring dynamic and realistic enemy behavior in combat.

4. Efficient Object Pooling System

  • Challenge: Frequent object instantiations, especially for bullets, caused performance issues during intense firefights.
  • Solution: Implemented an object pooling system that maps pools to types using generic methods, enabling type-based retrieval (e.g., GetObject<T>). Preloaded pools can expand dynamically as needed, utilizing ConcurrentQueue for thread-safe management and HashSets for quick lookups. This design improved performance and ensured efficient reuse of objects without gameplay interruptions.

5. Vision and Hearing Systems for Realistic Enemy Reactions

  • Challenge: Create dynamic enemy responses to visual and auditory cues while avoiding redundant behaviors like repeatedly investigating the same locations.
  • Solution: Vision relies on spherecasting to detect the player within range. It checks if the player is inside a flat FOV cone defined by the enemy’s forward vector and angle. Hearing is triggered by actions or weapons emitting sound, using a distance-based check that scales with volume. Louder sounds alert enemies farther away and influence reactions, ranging from suspicion to full alert. Investigated locations are “forgotten” when enemies return to patrol, ensuring varied and realistic behavior.

6. Modular and Extensible Weapon System

  • Challenge: Creating a wide variety of weapons with unique behaviors required a modular system to prevent code duplication and simplify future additions.
  • Solution: Designed an inheritance-based system with a common interface, enabling interaction with weapons regardless of type. Weapons are categorized (e.g., melee, ranged) with specific subclasses for semi-auto, full-auto, and explosive functionalities. Each subclass manages properties such as fire rate, magazine size, and reload time. Optional modules, such as silencers, are implemented as components. This structure simplifies integration of new weapons and ensures compatibility for both player and enemy usage.

7. Animation Event Management for Precise Gameplay Timing

  • Challenge: Unity’s animation clip event system relies on Unity messaging, which cannot interact directly with non-MonoBehaviour classes, complicating gameplay actions like reloading or triggering impact effects in non-MonoBehaviour code.
  • Solution: Created a relay system to convert animation clip events into C# events, allowing non-MonoBehaviour classes to subscribe and handle them. This enabled precise synchronization for actions like playing reload sounds at the exact moment a magazine locks in place or spawning blood effects when a character hits the ground.

8. UI Management and Dependency Injection with Zenject

  • Challenge: Displaying dynamic information like health, enemy awareness, and objectives required efficient dependency management as the game increased in complexity.
  • Solution: Used an MVC-inspired pattern to separate data handling, presentation, and logic. Integrated Zenject for dependency injection, simplifying connections between HUD, menus, and in-game prompts. This modular architecture enhanced maintainability and scalability, adhering to SOLID principles and facilitating future updates without major code changes.

9. Game State Management for Consistent Gameplay Flow

  • Challenge: Managing game states (e.g., active, paused, game over) required consistent responses from all game elements while allowing specific behaviors like ongoing animations during pauses.
  • Solution: Developed a centralized game state manager that triggers events (OnPause, OnGameOver) for dynamic, independent responses. Pausing freezes gameplay elements without disrupting animations, while the game over state allows systems like enemy movement to continue even after the player’s death.

Future Development

  • Enhanced AI Search Patterns: Improving enemy search logic for more realistic detection and pursuit behaviors.
  • Mini-Map Implementation: Adding a mini-map to aid player navigation and spatial awareness.
  • Enemy Weapon Pickup: Allowing enemies to retrieve and use dropped weapons or engage in melee attacks when unarmed.
  • New Weapons & Utilities: Adding grenades and flashbangs, with stun effects for flashbangs to expand tactical options.
  • Gamepad Support: Adding full gamepad compatibility with the new Unity Input System.
  • Additional Mechanics: Introducing a hostage taking mechanic and security cameras for more complex stealth challenges.

Key Takeaways

This project was a rewarding exploration of AI, modular system design, and the challenges of responsive, stealth-based gameplay. The state machine architecture, coupled with custom sensory systems and modular weapon design, allowed me to create a highly interactive environment. The experience emphasized the importance of structured code for scalability, particularly in handling AI behaviors, weapon interactions, and UI complexities. This case study highlights the potential for future expansion and refinement to create a more immersive stealth experience.

Have a Project in Mind?

Let’s chat about how I can help bring it to life.

I’ll get back to you within a day.

Get in Touch