Project Description

In this project my goal was to make a mobile game in Unity Engine. Due to using an engine, my focus was on trying to make an immersive game where there is a lot of feedback and room to improve the game over time. This is just the foundation of the game, showing the core mechanics and game modes.

The basic idea is to try and get the highest score in survival. In order to get better weapons, the player must traverse through a randomly generated dungeon and kill the final boss to unlock a new weapon. This weapon can then be used to try get a higher score in survival. Who can obtain the highest score?

Video of Gameplay

I think that the feedback of the game makes the player feel immersed in the world and overall enjoy the experience. There are some gameplay features that could be improved - such as the enemy pathfinding, and refining the getting weapons. A couple extra enemy types as well as boss types would also make for a better experience, with how I created the enemies from Scriptable Objects, is very easy to add.

Procedural Generation

In the dungeon game mode, the dungeon is created procedurally at run time. This is done in a few steps. The first step is by dividing the size of the grid using Binary Space Partitioning. This then creates the foundations for the rooms. The centre of each "room" is then taken and iterations of the Random Walk Algorithm is used to create random rooms shapes. Once that is completed, the rooms can now be connected using corridors. At this stage the players position and boss's position is created. The boss will be in the furthest room from the players starting point. Now the final iteration of the level can take place. This involves iterating over each of the floor and determining where the walls should be placed.

Enemy Generation

The enemy generation, specifically the boss generation is random. The randomness is choosing a boss type at random (currently two types: A "tanky" slow boss and a weaker faster one). Then they are given a random bullet prefab on spawning. This makes for the dungeons to be re-playable with the addition of more bullets and boss types.

The enemies are spawned at random from a random spawner. This spawner is either chosen from the rooms (Dungeon) or from game objects (Survival). Once a spawn location is chosen, an enemy is created based off some rates, for example, a weak enemy can have a 70% chance to spawn, and a higher health tough enemy can spawn the remaining 30%.

Each of these systems were created with the idea that they would be expanded on in the future. If an additional boss type is desired in the future, the data can be filled in the Scriptable Object, animations set, and prefab linked to the data, and you have a new Boss type!

Enemy Pathfinding

Enemy Pathfinding is broken into two different types. In the dungeon they use A* pathfinding using the A* project package. This package assists in doing the actual calculations however it is not a perfect solution as it does not consider the entities width when smoothing the path. This causes enemies to get stuck on corners. To try reduce this I offset the A* grid by 0.5 units and make the corridors 2 tiles wide for the enemies to traverse through. It is not a perfect solution as they still occasionally get stuck, and if there procedural generation results in a 1 tile gap, the enemies cannot traverse through this, so a player can see unexpected behaviour if camping there. Overall the solution is sufficient due to the fact that the player has to find the boss in order to progress, meaning they will eventually have to move.

In survival, to be more efficient, the enemies just move towards the player. It is not a perfect solution due to enemies potentially getting caught at the bottom. However, I do not think this is a problem since it is survival, the player has to keep moving around to survive, so the enemies will get stuck very few and far between due to the players constant movement.

Data Persistence

Players information is stored on their local device using binary serialization. This information includes an inventory of which guns the player has obtained, which gun is currently equipped, player information and stats such as deaths, kills, and name (note that the deaths and kills are only for survival game mode – this is due to the fact that the challenge of the game is to survive the longest, therefore it tracks that game mode).

Player Feedback

As I mentioned previously, due to using an existing engine, my goal was to try create a game that feels good to play, this was by focusing on the feedback.

Some feedback that I added:

  • Flash on entity damage

  • Dissolve shader on entity death

  • Dash feedback with use of trail

  • Sound effects

  • Blood splatter (Using unity mesh)

  • Bullet casings (Using unity mesh)

  • Camera shake

  • Damage number pop-ups

  • Muzzle flash

  • Background audio

Weapon Stats UI

When selecting the game mode, there is a screen where the player can select one of their unlocked guns. This screen compares the different stats at run time. This also includes highlighting the better stat in green and worse in red. If both starts are equal, it favours the equipped gun – hence that stat will be green.