Samuel Håkansson - Portfolio

Gameproject 3

Logo
Info

This Game Project was a 5-week group project developed in Unity using C#.

The goal of the project was to make a wave-based zombie shooter, inspired by the Zombies game mode from the older Call of Duty titles.

I was responsible for most of the programming (excluding the multiplayer networking). My main responsibilities were designing and developing the core gameplay systems and features such as the wave spawning system, weapon framework, interaction system and enemy AI. I also contributed by making the player controller, player HUD / in-game UI and the audio manager system and parts of the power-up functionality.

A major focus during development was reducing the amount of work required to add new content by building modular and scaleable systems.

Wave Spawner

(Zombies spawning and Spawn Locations dynamically changing based on the players location on the map)

Logo

The Wave Spawning System was my main resposibility. The main spawning script handles the spawning logic with a couple configuable variables, that being, EnemyCap and SpawnDelay. It also hold a list of EnemyTypes.

When a new round starts, it iterates the wave number and then checks if the round is a "Special Round". After which, it updates the spawn amounts.

The spawner adds enemies to a queue based on the spawn delay, sets their health, and inactivates them.

If the spawner finds an availible spawn point from it's list, it removes an Enemy from the Queue and updates it's position and then adds it to another list of spawned enemies.

Once spawning of new enemies has concluded and all enemies are dead, a new round starts automatically.

Logo
Logo

(Left) Spawn Points | Map Locations (Right)

Now for the spawn points. There are two prefabs, the SpawnPoint and the MapLocation, which handle updating the spawners available spawn locations.

• The SpawnPoint is the location where the Enemies spawn. It checks if it is eligible to spawn an enemy, based on a delay.

• The MapLocations has a hitbox and also a list of spawn points inside of it.

The addition and removal of spawn points is handled when the player enters/exits the various map locations. This made it very easy to add new zones and spawn points or modify existing ones.

Logo
Logo
Interaction System

The Interaction System is built on a base class (InteractableObject), which handles the players interaction state and eligibility as well as the UI through the use of an enum and switch case. The actual functions are implemented individually inside of the derived classes through a virtual "Interact" function from the base class that is then overridden.

The InteractableObject uses a trigger hitbox to detect when the player is in range.

When the player enters the trigger, the object is then stored as a variable in the player, and upon input the Interact function is called on the from the InteractableObject.

Using a base class made it easy to add new InteractableObjects, as it removed the need to modify the players code, and only required minor additions to the base class.

Weapon System

The weapon system was built using a base class "Gun" that implements the shared functions that all the guns would have such as, TryShoot, HandleShoot, TryReload, Reload, ADS (Aim). Then the "Shoot" function is implemented sperately via an overrideable function to allow for different shooting behaviours for each gun.

Logo
Logo

Weapon stats and general data were stored inside of Scriptable Objects, which allowed for them to be easily adjusted and tweaked with minimal effort without changing the weapon code.

To make the weapons feel more different, I implemented different shooting behaviours for two of the weapons, namely the Rifle and Shotgun.

The Rifle has bullet penetration, meaning it can shoot through enemies. Also with a variable to decide how many times it can penetrate.

The Shotgun has bullet spread with variables added for how many "pellets" it should shoot as well as Spread X/Y for the intensity of the spread.

I also implemented the ability to Uprade weapons. This would change the stats by swapping the GunData, additionally, the muzzleflash and firing trail VFX that played would change. Specific parts of the weapons would get a new material which I used a "useMaterial" tag to do.

Logo Logo

The existing weapon framework made adding new weapons a straight forwards process that allowed for a previous weapon folder to be duplicated, followed by renaming of assets (Script / GunData), with minimal additions elsewhere.

This made the whole system very scaleable and saved a lot of time during development.

Enemy AI

The Enemy AI is based on Unity's NavMesh Surface and NavMeshAgent systems for navigation, while the targeting, combat and other behaviour is implemented using C# code.

When spawning, each Enemy gets pick the closest player to themselves as their target. They also get randomly asigned a movement speed (influenced by the current wave number), which dictates if they should walk or run and sets their animations accordingly.

To keep the gameplay flowing, if an enemy ever gets to far away from the player, they get despawned after which the spawner queues a new enemy as a replacement.

One of the power ups in the game temporarily hides the player from all enemies. Any enemy that happened to be targeting that player will lose it's target and attempt to find a new one. If it can't find another valid target, it will remain in an idle state until a valid target is found.

When a player moves within the enemy's attack range, it stops navigating and initiates it's attack. Before dealing damage, a second distance check is done to make sure that the player is still within range, preventing attacks from hitting the player if they move away. They also have an attack cooldown to control how frequently they can attack.