Specialization

Weapon System
  • Engine – Unity (C#)
  • Time – 2 weeks, 20h/week

Inspired by the fluid combat of CS2 and Titanfall 2, I developed a generalized weapon system in Unity (C#) that prioritizes “game feel” and extensibility.

Key Technical Decisions:

  • Generalized Architecture: Developed a single, robust weapon controller that utilizes public parameters (e.g., fire rate, spread, bullet count) to instantly transform from a semi-auto pistol to a multi-pellet shotgun.
  • Focused Scope: Prioritized first-person ranged combat to maximize the quality of animations and feedback within the project timeframe.
  • Inspector-Driven Balancing: Designed the system to be highly iterative, allowing for real-time tweaking of recoil patterns and fire modes directly within the Unity Inspector to find the most satisfying gameplay loop.

Features

In this section I will be talking about the different features added to the weapon system.

List of Features:

  • Shoot w/ Modes
  • Reload w/ Modes
  • Modular Projectiles
  • Spread
  • Recoil Pattern
  • Customizable & Dynamic Crosshair
  • ADS (Aim Down Sights)
  • Animation & Animation-based Actions

Shoot & Modular Projectiles

For ranged weapons, the most basic and important feature is the ability to shoot. A weapon that cannot fire is effectively useless, leading to a dull experience.

Initially, I planned to handle projectiles as hitscans. Hitscan is a method where each projectile is represented as a ray, making travel time immediate and feedback consistent. Since rays aren’t physical objects, they minimize the performance hit in fast-paced shooters with high projectile counts.

However, I realized hitscans fall short for weapons like an RPG, where slow-traveling projectiles are necessary for balance. While you can “fake” travel time with rays using distance = velocity x time, this struggles with dynamic objects. By using physical objects, I achieved Modular Projectiles. This allows for total freedom; you can even have a physical projectile that acts like a hitscan.

So, how do we shoot?

By letting projectiles handle their own logic, the weapon becomes a “glorified spawner.” In Unity, this is a simple matter of instantiating the selected projectile. To keep the system modular, I added:

  • Shoot Mode: Semi-automatic vs. Automatic.
  • Fire Rate: Dictating shots-per-second.
  • Projectiles Per Shot: Allowing for shotgun-style spreads.
  • Burst Logic: Separated from Shoot Mode, using “Bursts” and “Burst Rate” to control multi-shot sequences in parallel with other firing modes.

Reload

For weapons with limited capacity, the reload system is critical. I designed the reload logic to be context-aware, handling different weapon types through a single system:

  • Magazine vs. Incremental: A pistol might replace a full magazine at once, while a shotgun loads shells individually. To keep this modular, I added a parameter to define how many projectiles are added per reload cycle.
  • Reload Speed: A simple timer-based variable that dictates the duration of the reload animation/action.
  • Cancellable Reloads: To increase player agency, I implemented a Reload Cancel feature. This allows the player to interrupt the reload mid-way (essential for shotguns where you might need to fire a single shell you just loaded) or abort the process entirely via a button press.

Spread

Real-world shooting is rarely perfectly precise due to human error and mechanical variance. In this project, I represented these factors as Dynamic Spread; a spherical constraint that forces bullets to deviate from the center-aim vector.

Technical Implementation:

  • Vector Deviation: By calculating a maximum angle between the gun’s aim vector and the projectile’s initial trajectory, I created a controllable “cone” of fire.
  • Bloom & Recovery: I implemented a Min/Max Spread system. Continuous firing causes the spread to “bloom” until it hits a maximum threshold, while pausing allows it to settle back to its minimum.
  • Movement Penalty: To reward tactical positioning, I added a multiplier that increases spread while the player is moving, encouraging “stop-and-pop” gameplay.

Recoil Pattern

To elevate the skill ceiling, I implemented a Deterministic Recoil System inspired by Counter-Strike. Instead of simple random nudges, each weapon follows a consistent, learnable pattern, allowing skilled players to “counter-steer” their mouse to maintain perfect accuracy.

Technical Implementation:

  • Dual-Curve Architecture: I utilized two AnimationCurves (Horizontal and Vertical) to define the recoil path. By mapping the x-axis to the “firing duration” or “shot count,” I can precisely control the weapon’s trajectory over time.
  • Wrap Mode Optimization: I utilized different wrap modes for distinct behaviors: Clamp is typically used for Vertical recoil to prevent indefinite upward climbing, while Loop is applied to Horizontal curves to create consistent side-to-side “sway” during sustained fire.

Customizable & Dynamic Crosshair

Crosshair Examples

Reactive Crosshair

To bridge the gap between mechanical spread and player perception, I developed a customizable, reactive crosshair system. While currently using circle textures for simplicity, the system is designed to be fully modular, allowing for easy visual swaps.

Key Features:

  • Visual Feedback: The crosshair dynamically expands and contracts based on the current spread/bloom values, providing real-time feedback on accuracy.
  • Customizable Behavior: Players (or designers) can toggle movement for individual components, choosing which parts of the reticle remain static and which react to the firing state.
  • Texture Modularity: By utilizing texture-based pips, the visual style can be swapped instantly without affecting the underlying logic.

ADS (Aim Down Sights)

To complement the dynamic spread system, I implemented an Aim State that provides a tactical alternative to hip-firing.

Technical Implementation:

  • Dynamic FOV Scaling: Transitioning into the aim state triggers a smooth Field of View (FOV) reduction, creating a magnification effect that enhances long-range engagement.
  • State-Specific Accuracy: I designed the system to utilize unique spread values for each state. Aiming significantly reduces the Min/Max Spread, rewarding players who take the time to stabilize their shots.
  • Visual Alignment: The weapon model shifts into a designated “ADS position,” aligning iron sights or optics with the center of the screen for precise manual aiming.

Weapons

Weapons I created with the help of my tool

Pistol

Pistol (no burst)
Pistol (with burst)

Shotgun

Pump-action Shotgun
Automatic Shotgun (with more spread)

Assault Rifle

Classic Assault Rifle

Submachine Gun

Simple Submachine Gun

Rocket/Grenade Launcher

Rocket Launcher
Grenade Launcher

For Fun

Monstrosities I created with the help of my tool 🙂

Reflection

Did I achieve a flexible weapon system? Yes. I was able to create various weapon archetypes with ease and, in theory, the architecture is modular enough to support melee weapons as well.

However, no system is perfect. In my pursuit of flexibility, I encountered the “decoupling paradox”: while separating components allows them to work independently, over-engineering this separation can lead to increased complexity and a loss of cohesion. I can sense this beginning to affect the maintainability of the project.

Furthermore, the communication between the player and the weapon remains a key area for improvement. Currently, the system lacks a finite ammunition loop, which is a missed opportunity for player tension and satisfaction. Moving forward, refining the “inventory-to-weapon” communication and cleaning up the internal architecture would be my top priorities.

Credits

Assets I used for some of the graphics, vfx and sfx

Reload SFX: Reload.mp3 by LAGtheNoggin — https://freesound.org/s/15545/ — License: Sampling+

Gun And arm Model/animation: “animated pistol” (https://skfb.ly/ooPqJ) by DJMaesen is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).

Beer Bottles: “Empty beer bottles” (https://skfb.ly/or8ZG) by Ricardo Sanchez is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).

Glass Break SFX: RBH Glass_Break 01.wav by RHumphries — https://freesound.org/s/977/ — License: Attribution 4.0