General/Credits

Aside from the art and sound, I made the entirety of this project from scratch.   I purchased the haunted town environment art on the Unity Asset Store for $10 during a Halloween sale, the zombie model and animations were free on the Asset Store, and the guns and their three respective animations (reload, shoot, draw) were from a download that used art from Call of Duty Modern Warfare 3 (and thus cannot be used for commercial use).  The audio was mostly taken from YouTube to MP3 conversions that I then edited and exported from Audacity (free audio software).  

Below I have documented both the design and integration process of these art and sound assets into a fully playable game.


The Guns

The first thing I needed to do was get the core first person shooter gameplay up and running.  The first step to this was creating a functioning gun and attaching it to a first person character controller.  For the guns, I used a polymorphic approach by creating a base gun class with a variety of properties and methods that were applicable and usable by all of the gun models and animations.  I set it up in such a way that all of the gun statistics are editable in the inspector for easy tweaking purposes, and any new gun model with the appropriate animations could easily be integrated into the existing system. 

The flexibility of the class allowed for manipulating all sorts of gun properties including rate of fire, full or semi automatic, draw speed, recoil amount(spread when firing from the hip), ammo capacity, mag size, etc.  The Vector3 "Aim Target" was the only hard coded number on a per gun basis.  Because the guns didn't have an aim down sight animation, I manually positioned them to where the barrel was in line with the center of the screen and copied the modified local transform position.  I then used a Lerp between the guns starting and aimed position while Lerping the camera's field of view to create a zoom/aiming effect when the player holds down aim.

For bullets, I used a RaycastAll method which returns an array of all colliders hit in a straight line from the barrel of the gun.  I kept track of whether or not a zombie was hit and in what order such that the array stopped hitting enemies after a certain amount (to simulate max bullet penetration), and decremented the damage value by 10% for each subsequent zombie that was hit.  For example a zombie that was behind three others in a line would take 30% reduced damage of the guns' damage value (either body or head).

Finally, I needed to add gun effects.  For muzzle flash, I used a 2D texture that was warped into a pyramid shape and a point light at the barrel.  When fired, these two objects briefly flash producing the effect.  Additionally I added shell casings that appear and fly off the side of the gun with every shot.  To enhance this effect, I added a shell landing sound at the end of each gun fire audio so that the player could hear the clings of shells landing on the pavement. I put an empty game object between the camera and the first person controller and attached a custom recoil script so that the camera's Euler angles could change independently from the mouse input to create a visual kickback on each shot.  For the G36 and the M4 I had to play around with the scope lens texture property, but was finally able to make the red portion emissive so that the red dot sight would appear lit up and easy  to see against any backdrop.  All of the guns function off of animation events to drive reload sounds and functionality.


The Character

The next step was controlling all of the playable inputs on a first person controller.  I used Unity's built in FPS Contoller and made some slight modifications along with a custom Character class to create the playable character.  The Character class had an inventory system that contained two gun slots.  It controlled all of the gun related input methods (like when to reload and fire) as well as swapping weapons, and purchasing weapons/ammo off of the wall.  Additionally, this class housed the player's score which was used to determine if they had adequate funds to purchase barriers or guns.

I created the knifing animation and state (using a duplicated version of the Glock hands without the gun), and used a basic trigger to detect what the player had hit and to play a sound accordingly (adding some squish if you sliced a zombie).  I also created a stamina system so that the player would not have unlimited sprint. While the player is sprinting, I used a Slerp (spherical linear interpolation) method between the gun's starting Euler angles and a "tucked" position to simulate a sprinting animation.  While I was play-testing, I found that the zombies wouldn't be able to consistently hit the player if you repeatedly jumped.  To fix this I incorporated jumping into the stamina system so that jumping also drains stamina, and you need a certain amount in order to jump and sprint.

The Character class also held references to most of the UI so that with a simple UI Update method, all of the changes could occur.


The Zombies/Rounds

Now that the player could move and shoot, they needed something to shoot.  The zombie behavior itself was very straightforward to create.  In fact I refactored a lot of the AI from a previous demo project (The Blacksmith).  The zombies move around via a navmesh (the blue path), and attempt to attack the player when they get too close.  The barriers are all carving the navmesh at run time, so when they are purchased, the mesh fluidly connects the new area to the existing walk-able path. 

I created colliders for each of the zombies' main body parts, and passed that information to the guns when they were shot, accordingly.   This enabled the player to do more damage on a headshot, as well as award more points and play a satisfying squish sound on a headshot kill. 

The zombies have different speeds, sounds and animations, which were all handled by the Spawner class.  

Spawner:

I subdivided the level into separate parts, and had several spawn locations per part.  These spawns were inactive until the player purchased a barrier that opened up their respective area.  Whenever a spawner would attempt to spawn a zombie, it would perform a distance check to the player.  If a spawner was too far away, it would relegate its spawn to a different object so that the zombies would spawn in a relatively localized cluster around the player's current position.  This was to allow the player to have some option of escape while moving around the map, and to prevent the player from getting boxed in the horde immediately.  

Rounds:

All of  my zombie data (such as number of zombies per round and health) are based on the actual numeric values in the Call of Duty games.  I found some awesome forums that had equations for those exact metrics, as well as accurate gun statistics.  As rounds progressed, I incorporated my own equation to determine how many of the zombies should spawn as running vs. walking.  Past a certain speed threshold they would use the run animations instead, and would make screeching yells as they chased you instead of mindless zombie groans.


Gameplay & Level

There were several exclusions I had to make compared to some of the features in the CoD Zombies games.  All of them were mostly due to lack of appropriate art assets.  For example, it would have been easy to create a barrier/border system that would keep the zombies out, however the zombie model I had did not have pulling and/or climbing through animations.  The overall visual fidelity would have been lower if I reused the attack animation and made the zombie float through the barrier, or have a visually walk-able area that the player could not get to.  Additionally, I would have liked to have had a mystery box which cycles random guns for the player, but with only 6 guns in the game, and 5 of them being purchasable from the wall, it would have been a lame mystery box indeed.

As far as power-ups, I used three familiar ones (Max Ammo, Instakill, Nuke) and created a custom one called Bullet Time which slows time in half but allows the player to aim the gun at real-time speed.  This mechanic/power-up is largely based on the Killing Floor 2 slow motion, as I thought it would be appropriately fun/cool in this zombies environment.

The level was designed with the original Nazi Zombies map "Nacht Der Untoten" in mind.  I wanted it to follow a compact nature and have varying levels of elevation.  The art pack I purchased is modular, meaning that you get a variety of different assets such as walls, windows, roofs, etc, and you can arrange them to create both facades and interiors (kind of like Lego). 

There are three distinct areas on the map, the courtyard, the inn, and the catacomb tunnels.  I priced the guns and barriers around a point progression associated with the rounds, and based on their prowess.  The better the gun is statistically, the more expensive it is to 1. reach its wall location and 2. buy it.  I wanted to preserve a bare-bones nature to the game and make it particularly challenging by excluding perks (such as faster reload, upgraded guns, more health), and large open areas where the player can easily create "trains" of zombies.  In fact, in order to purchase additional ammo for the best guns, the player must navigate tight corridors and interior space.  To compensate, I allowed the player to survive two hits from zombies, dying on the third instead of one hit and dying on the second.

Like all Zombies maps, I included Easter Eggs.  The musical Easter Egg is obtained from knifing all of the torches found throughout the map and plays "For Whom the Bell Tolls" by Metallica, a perfect zombie-slaying song.  Additionally I included a wonder weapon on the map (the Kitten Kannon) which is accessible by overcoming a bad batch of mushrooms and knifing (but not killing!) all of the kittens you find.