Zombie Shooter 3D
(Unity)
Roles:
Level Designer,
Tech Designer
Year
2023-24
Team:
Solo Project (DigiPen Design Capstone)
Links:
~
Description:
Zombie Shooter 3D is a solo project designed as a first-person shooter game in the setting of a zombie-infested facility. The player has to rely on their puzzle-solving and sharp-shooting skills to make their way out. Throughout their adventure, the player will have to solve numerous challenges, find 3 powerful weapons, and fight 4 unique enemy types including a zombie boss.
Trailer Mock-up
Contents
-
Original Idea
-
Technical Design
-
Core Mechanics and Interactions
-
Enemies
-
Lighting
-
Game Design
-
Core Mechanics and Interactions
-
Level Design
-
Combat
Original Idea
This prototype was created as a part of the 6-month DigiPen Personal Capstone Project course. For this senior course, I had to demonstrate my skills in 2 design disciplines that I studied during my program, showcasing my progress, abilities, and experience earned at DigiPen. The disciplines of my choice were Technical and Level Design.
The game’s core gameplay loop was highly inspired by the Resident Evil series, and the visual style took references from Silent Hill 2. The idea was to make a simple first-person survival shooter from scratch, that will have enough gameplay mechanics to build creative levels and designs yet keep it simple enough to be achievable in 6 months of solo work.
Due to the nature of the class, the development was separated into 2 main stages, pre-production, and production. During the pre-production stage, I mostly worked on the technical implementation of gameplay mechanics and tools that would later help me to build the main content. During the production stage, I filled the prototype with content, using the tools created during the previous stage, making an exciting experience and polishing details.
Technical Design
The main target of pre-production was to build a technical foundationfor the game, as well as to prototype a vertical gameplay slice demo to see which parts of my design work well and which ones are lacking. Therefore, this stage was mostly dedicated to Technical Design.
Core Mechanics and Interactions
I began prototyping the core mechanics of the game, starting with the player controller. The player controller had to have the following features:
-
4 states (Walking, Running, Crouching, and Aiming)
-
Manage player inventory (Ammo and Reload Logic, Health, Weapons Collected)
-
Manage player progress serialization (Save/Load system for player inventory and level progress)
-
Manage shooting (Weapon switch, Weapon Visualization, Bullet Spread)
After prototyping these features, I started extensive playtesting in order to find potential issues and improve sharp angles.
The jumping mechanic turned out to be unreasonable in the current context and was cut. The ammo reload logic had to be more complex than I expected and required several variables to keep track of the current magazine load, total ammo count, maximum magazine capacity, and a reload algorithm that will resupply the current magazine depending on how full it is at the moment. The player controller required me to build a finite state machine to handle all of the possible player states and transitions between them (Ex. crouching to running, running to aiming, etc). The player inventory serialization and saving implementation was simple but required many more variables than I expected, including the information about the current weapon held and the current magazine load for each weapon.
The shooting had to go through several waves of iteration due to the fps parallax effect. The challenge was to make the bullets hit the exact spot where the UI crosshair aimed at, having physical bullets spawn at the gun’s tip in the bottom right corner of the screen. Making the bullets physical rather than having them as a raycast gave several benefits to the shooting experience; real-time bullet path visuals, bullet physics, and complex interactions, bullet ricochet. In order to implement this feature, I had to learn how the parallax issue was addressed in other games and took my solution from Quake 2 and Warframe shooting logics, where the gun’s tip is being pointed toward the crosshair target dynamically adjusting the bullet path to be towards it.
One other very important system that I implemented was the interaction system. It consists of 2 components, the trigger component and the listener component. When the player interacts with the trigger component, it sends a message to a predetermined listener on the scene, commanding it to do a function of choice from its list of functions. The listener function includes: spawning/removing objects, spawning UI pieces, playing animations or sounds etc. This system allowed me to build unique level events and elements such as doors and buttons without relying on hard-coding my in-game events.
An example of a trigger script that invokes several outside functions using a serialized list of Unity Events
An example of a trigger script that invokes several outside functions using a serialized list of Unity Events
Enemies
The enemies were a big challenge to make. Apart from being standard NavMesh bots, they also had to have a smart player detection system, allowing the player to stealth through or hide from them, as well as a decapitation system to make the sharpshooting more fun and rewarding.
First of all, I developed a health/damage system that handles receiving and dealing damage between the enemies and the player. When a bullet touches a hitbox, it detects what kind of object it is, plays appropriate particle feedback and if it’s an enemy, sends the damage information to its health component.
To implement decapitation into the game, I had to create a special model for the enemies, where each body part was a separate mesh that could be turned on and off. Then I assigned separate colliders and damageable components for each body part to correctly register the damage. Once a body part is damaged, it multiplies the damage received (x1 if normal body part, x4 if head) and sends it to the core enemy health script that handles the total enemy health. Then the body part subtracts this damage from its personal health, and when it reaches 0, it removes itself from the model.
For the navmesh agent, I implemented a 6-state FSM that included states like idle, chasing, attacking, returning back to the original position, and dying. The component can also hold a list of game object positions. If the list has 2 or more entries, the enemy will be patrolling between these 2 positions during the game.
Another big system I implemented was the player detection system. It uses a combination of a raycast and a trigger collider to see if the player is visible to the enemy. When the enemy sees the player, it starts chasing them. If the enemy loses the player from its sight, then it’ll go to the last place where it saw the player and investigate it for a couple of seconds. Once that time passes, the enemy returns back to its original position or continues the original patrolling path.
The majority of the enemy roster (Normal Zombie, Explosive Zombie, and Armored Zombie) was made using the exact components described above, with their values adjusted to give them new functionality. For example, the Armored Zombie has some of its body parts lacking an individual health component, making the bullets deflect from those body parts (As handled by the bullet collision script). The Explosive Zombie, on the other hand, has the damage multiplier on his belly to be X8, which instantly kills him after being shot in it, and his dropped loot list has the explosion prefab instead of ammo, which makes him explode on death. As you can see, this system is extremely modular and allows you to implement many different enemy types with different meshes and animations without having to do any scripting.
However, there is also a unique Boss Enemy that was implemented later in the development. At its core, it inherits many of its components and interactions from the common enemies, which makes it work with all of the enemy mechanics implemented prior (Like the damage system, serialization, etc.). Those components, however, were modified for the sake of the boss battle.
The boss has a 7-state FSM, which includes idle, walking, deflecting bullets, close combat attack, projectile attack, stagger, and death. To learn more about the boss mechanics see the design section.
<--- Swipe to See More --->
While the character models might seem simple, they utilize a huge spectrum of technologies
The enemies use a combination of trigger and raycast methods to accurately detect player visibility
While the character models might seem simple, they utilize a huge spectrum of technologies
Lighting
Lightmapping this game was a big challenge and a valuable learning experience for me. Unity Engine doesn’t have a good solution for indoor non-ambient lighting, having extremely unperformant point lights in real-time global illumination mode. Due to that, the game heavily relies on baked lighting and light probes, making lightmapping an individual task done by hand. While lightmapping this level, I learned a lot about the correct positioning of light probes and reflection probes and different URP features that help with game optimization. I had to be very selective about which lights I bake and which lights remain realtime, to avoid performance, yet have dynamic shadows in the rooms with moving elements like doors or hatches.
<--- Swipe to See More --->
Light probe groups are used to simulate real-time lighting for moving objects in a baked environment
All level props are optimized to have little to no faces in places invisible to the player, to improve the performance and bake time
Light probe groups are used to simulate real-time lighting for moving objects in a baked environment
Game Design
Designing an FPS game from the ground up might sound like a complex task. Luckily, I did research on numerous FPS titles. My main references were: Quake 2, Half-Life, Resident Evil 4, S.T.A.L.K.E.R., Overwatch, and Metroid Prime. The core gameplay mechanics in this game were shooting and traversal, which is why I had a big focus on utilizing them in many interesting ways. For example, in this game, shooting is not only used to damage the enemies but also as a way to interact with certain objects.
Core Mechanics and Interactions
The biggest point of reference for my player controller was Overwatch. I wanted the movement to feel smooth, yet extremely precise in terms of geometry. To achieve the effect of smooth acceleration and deceleration, avoiding the character “drift” effect, I made an extremely precise player controller and connected a spring camera to it. The controller allows the player to make accurate moves and the spring camera chases it creating an illusion of acceleration and deceleration, creating an effect similar to the Overwatch character controller.
The shooting mechanic was inspired by Quake and S.T.A.L.K.E.R. I wanted the weapons in my games to shoot actual physical bullets instead of just raycasting the hits, to make the shooting feel more controllable and satisfying. To reinforce that effect, I added a tracer tail to the bullets, making them very easy to track while shot, and allowing to make precise shots without aiming for too long. I also added different particle effects for different bullet collisions. That particle and sound feedback help to signify to the player if their shot damaged the enemy or hit their invulnerable part.
The level interactions were inspired by Resident Evil and Metroid Prime series. The simple interactions like looting, opening doors, and hatches mix up the gameplay between the combat bits. The more complex interactions like the shooting range puzzle, allow the player to utilize their main skill (shooting) in different non-combat ways.
As for the signifiers, the game uses color coding to imply certain interactions the player can have with the environment. All of the interactive objects in the game are emissive (glow) and have a hand icon pop up when the player looks at them. Additionally, all of the shootable objects are golden-yellow. This helps to signify that the zombie heads are more vulnerable to damage and must be shot, the red barrels are explosive and the shooting range targets are interactive.
<--- Swipe to See More --->
Color coding is used as a signifier for different interactions
Different ammo types have different colors, making it easy to differentiate.
Emissive loot is easy to find, no matter the size or the environment conditions
Color coding is used as a signifier for different interactions
Level Design
Planning out the level design for this game was an extremely interesting yet educational experience. First, I wrote out the main concepts, rules, and mechanics I wanted to have in my game. I also researched common corridor and door proportions to make the space feel more believable.
Then I planned out the level geometry on paper. My main source of inspiration was Half-Life, where the level geometry itself is an interesting object to interact with. After creating an interesting core for my levels, I started filling them with the list of things I wrote out earlier. In my levels, I wanted to utilize all of the mechanics the player has and reimagine some of them from a different angle. I added hatches and ventilation shafts to make the player use crouching more, added the chase segment to tutorialize running, and added explosive barrels and the shooting range puzzle to make the shooting mechanic more interesting.
The core level philosophy was to make the environments as “open” as possible, allowing the player to freely explore the location. The level progression was inspired by the Resident Evil and Silent Hill series, where the player has one open location that expands as the player unlocks new parts of it by finding keys and passwords.
An example of that would be the second level, which is centered around an 8-shaped corridor. This corridor has many doors and rooms for the player to freely explore, however, all of the progression rooms are locked, and require the player to complete certain challenges to open them.
Each challenge is built using a unique level design structure I use:
Gameplay Bit Structure
-
Introduce the context.
-
Introduce the objective.
-
Introduce the variables.
An example of such a challenge would be the mentioned above shooting range puzzle. The shooting range puzzle starts by introducing the player to the context of the environment. In this case, it’s a shooting range. During this step, the player understands what they are and where they are at. Then proceeding forward, the player discovers the objective; a locked door with a counter above it. At this step, the player understands their current objective: to open the door. Then, once the player turns around, they see an interactable button. Pressing the button moves away the metal net, allowing the player to shoot the targets on the range. This step introduces the solution variables to the player. The player is not explicitly told what to do with the variables, but the color coding on the targets and the counter above the door makes it a nice little “puzzle”.
<--- Swipe to See More --->
The ventilation shaft elements compliment the walking gameplay with crouching episodes, making the crouching part of the player moveset purposeful
The set of building pieces used to construct the game's environment. Notice the rightmost cave module that seem to have uneven sides, but is completely compatiable with any piece thanks to the planar connector geometry
Combat
The interaction between the enemies and the player is the core gameplay of this game. This is why it was important to make the enemies interesting and provide a balanced level of difficulty that would excite the player. The enemy gameplay has a huge focus on sharp shooting (shooting into the specific parts of the enemy or the environment) as it is in Metroid Prime and the classic arcade rail shooters like the House of the Dead (where shooting is the only way for the player to interact with the game).
The default enemy is not too dangerous but requires the player to spend more than half of their magazine to kill if shot into the body. This enemy, however, rewards the player for shooting them into their relatively small head, by dying in 2 shots. This motivates the player to be more precise with their shooting and creates more gameplay tension where there are several such enemies or little time to aim.
The armored enemy is a bigger version of the default enemy. It, however, can only be damaged through its head and hands. This “mandatory headshot to kill” system is an evolution of the default enemy mechanic, that tests the player’s sharpshooting skill. It also teaches the player that they can shoot their enemies’ hands off.
The explosive enemy is a little different from the default and the armored enemies. Its color-coded face mask is much bigger and is located on its belly, signifying its weak spot. Once you shoot it, the enemy will explode, dealing massive damage to everybody nearby. In order to avoid the explosion and get the most combat benefit from it, the player has to have good positioning skills and utilize their environment.
The explosive barrel is not conventionally considered to be an enemy, but has a similar functionality to the explosive enemies, teaching the player the benefits of positioning and movement.
Finally, the boss enemy is the most complex enemy in the game. He is invincible to any damage (he deflects the bullets), shoots energy waves with his sword, and has a punishing heavy close combat attack that deals massive damage to the player if they get too close to him. From the early concept, I wanted this enemy to be big and mostly invincible to create a feeling of fighting a very powerful character. He cannot be overpowered or brute-forced, making the player think of a smart strategy to defeat them. Throughout the boss arena, there are explosive barrels that will stun the boss if they explode next to him. While staggering, the boss’s head becomes vulnerable to the player’s attacks. After a couple of seconds, the boss recovers and continues chasing the player. The player wins by repeating this loop 4-6 times. What makes this fight challenging is the luring process, during which the boss will shoot energy waves at the player. The boss is also the size of the corridor and will deal massive damage to the player if they try to run through it. This boss fight tests the player on most of the skills they acquired while playing the game, which includes sharpshooting, positioning, and resource management.
<--- Swipe to See More --->
The slashing animation is broken into 3 key movements that signify the hit timing
The boss staggers after being stunned with an explosive