Bring On The Bling

Gameplay Programmer/Technical Designer
Project Overview
You are a contestant in a virtual game show where you have to fight to earn money, but there's a twist! Your money is your health...

Fight through waves of enemies as the arena changes around you, unlocking upgrades with your hard earned money so that you can dispatch of the enemies more efficiently. Unlock temporary super abilities that allow you to dominate the battlefield.

Survive all 15 waves to win!
What I did
This project was a collaborative effort with 2 other level/systems designers, and an AI/Sound programmer. My focus on this project was Gameplay Programming. I was in charge of ensuring the moment to moment action of the game felt satisfying, fluid, and fast to the player. With these focuses in mind, these were my primary contributions to the project:

- Movement controller
- All gun logic(Firing, recoil, spread, etc)
- Upgrade targets
- Super abilities
What Went Well
Player Controller
Overall I'm very happy with the player controller. Though I use the Unreal Engine default player controller as a base, I implemented plenty of additional logic to it in order to make it feel heavily momentum-based. This gives the game a very fluid feel when the player is moving throughout the arena, and players have noted finding the movement particularly satisfying during playtests. Most of the logic was coded in Unreal 5's Blueprints, however the logic for the momentum based leaning/FOV adjustments were done through C++.
Old Player Controller
New Player Controller
Gun Logic
The gun logic went through the most iteration throughout the duration of the project, with the final result incorporating a number of different systems and feedback to provide a nice feeling gun that can be heavily tweaked and balanced by the designers. Some of the feedback is as follows: Camera shake, slight FOV adjustments, smooth recoil inspired by Rainbow 6 Siege, and a dynamic spread that increases as you fire longer uncontrolled bursts. Initially the gun's main logic was programmed almost entirely in Blueprints, but I have since refactored all of the main logic to C++ where applicable for the sake of optimization.
Super Abilities
The super abilities were also a nice addition that ended up being relatively easy to implement after I had refactored the gun's primary logic into C++. I was able to create separate firing functions for each super type, of which all having a similar base logic to the main gun's firing logic. This allowed me to quickly create three unique super abilities with ease. It was through this process I realized I quite enjoy working with C++ in unreal, even when prototyping new features where applicable.
Super Abilities
All of the above logic went through several iterations/implementations, and gave me nice practice in implementing C++ that works with Blueprints in a variety of different contexts.
Development Challenges
Though I am proud of the shape my contributions have taken now that they are mostly finalized, throughout the project I was met with several challenges that for a time had me hitting a wall. Here are the major challenges I faced and how I overcame them:
Blueprints to C++
The first major challenge I faced was refactoring my Blueprint prototypes into C++. Initially, I had intended to do so during the first half of the development of the game, however, I found myself needing to balance my time carefully between classes, and decided to focus more on implementing all of the required prototypes in Blueprints so we could meet our Milestone deadline. Over winter break, I had used my free time to go through all of those prototypes and re-declare all variables into C++. After I had done that, I went through and refactored major logical pieces of all of my prototypes into C++ entirely, with exception to things that were better kept to Blueprints due to their compatibility. This was my first time using C++ in Unreal Engine, but through refactoring these prototypes I was able to learn quickly enough, and now I find myself more often using C++ than Blueprints.
Smooth Recoil System
The second major challenge I faced was the creation of the smooth recoil system. Our initial recoil was very jarring to players, as it would instantly rotate your camera a set number of degree up, with a random left/right recoil per shot. There was no logic for returning the camera after recoil ended. This system, while functional, lead to a player feeling motion sick due to the jolting recoil that would happen very often. The lack of returning functionality also caused some players slight annoyance.
Old Recoil System
Due to this, I decided I would analyse the recoil from Rainbow 6 Siege, in hopes of recreating the smooth recoiling motion, but more importantly the logic for the camera returning to a dynamically changing 'origin point' so the player would not have to move their mouse manually after countering recoil. During the analysis, I wrote down a step by step breakdown of how the recoil seems to handle mouse movements in different directions during different phases of the recoil process, and how they affect the dynamically changing return position.
The process of creating the smooth recoil upward was easy enough, I recycled much of my logic, but had an enum stored in the gun that would keep track of what 'state' the recoil was in. With this enum I was able to create a switch statement in the update logic, within which I interpolated the camera, rather than setting it in one frame. This made the recoil feel much smoother overall, despite still being a very quick action. I applied a smooth step curve to it to create a more organic motion. The challenge came with the returning logic, as there were many cases where it would simply return to the wrong position entirely. I attempted 5 different implementations, but with each brought their own set of challenges. Eventually I was able to get the logic to work as intended, however this introduced a new problem.
New Recoil System
When the player would shoot singular shots while turning to face something, the return logic would force their camera very jarringly back to the return position. When I analyzed R6S, I noticed their return logic seems to get cancelled completely if you move your mouse too quickly while it's attempting to return. I then implemented a check that would happen only during the 'buffer' stage between the recoil and return stages, as well as the return stage itself. With some tweaking and adjustment so that it would be consistent among varied framerates, this fortunately did fix the issue.
Projectile Movement Hitboxes
In all of the above challenges, I was able to overcome them through continued effort and/or reaching out for additional support in order to accomplish the specific, unchanged goal. There was one case where the designers and I had decided to pivot. The challenge in this case was with the Unreal projectile movement component. This component simplified the process of creating the bullet prefab, however it had one major limitation: The projectile could only have one hitbox.
Piercer Ball Original Behavior
I was creating a larger projectile to be used for one of the super abilities. It needed to pass through enemies but still would need to be destroyed upon contact with the map itself. The hitbox was rather large, so in order to have the projectile not instantly get destroyed on a glancing contact with the ground, I had intended to create a secondary, much smaller hitbox, that would trigger the destruction of the projectile if it were to pass through a wall far enough to hit that smaller hitbox.

This ended up becoming an issue when I discovered the projectile movement logic only allows the hit/overlap events from one hitbox to ever be triggered. I was considering creating my own projectile movement logic from scratch. Though that would not have been a difficult thing to do, through experimentation with the other designers we had figured out a way we could adjust the behavior of the larger projectile to make it only require one hitbox, whilst also heavily diversifying it's use compared to the other super abilities.
Piercer Ball Bouncing Behavior
This adjustment was to have the larger hitbox bounce off walls. This simple change made it so the glancing hit would instead just redirect the bullet, which allowed you to also shoot it around corners and bounce it off walls in hallways to clear out a lot of enemies. We also decided to add gravity to the projectile so that it would stay lower to the ground, as with just bouncing the projectile would often bounce higher than the enemies heads. These changes served to make the super have an entirely different use case than the other supers, being able to clear hallways and rooms before you even turn the corner. These challenges led the super to be my favorite, as it is the most satisfying to use in it's final state.
How This Project Led to Growth
Though this was not my first game created in Unreal Engine 5, this project pushed me to become much more proficient with the engine. Throughout this project, I learned how to create Niagara particles, lighting, materials, and C++ code that both works independently and in unison with Unreal's Blueprints.

Being the sole Gameplay Programmer on the team, I also got to have a lot of ownership over the player controller, and was able to add plenty of feedback and make plenty of iterations on that feedback. This ultimately led me to meet my goal of creating a satisfying and fluid feeling FPS player controller.

Adapting the Rainbow 6 Siege recoil logic for this project gave me great practice for examining existing gameplay mechanics from an analytical lense, and involved plenty of game adjacent linear algebra.

Overall, I'm very happy with the development of this game. I feel that the things I've learned, as well as the challenges I've overcome, have led me to become a much better Unreal developer, but more broadly a better Gameplay Programmer/Technical Designer.