First Person Shooter + Input Combos

-- Project Summary --

-- Concept --

This was my specialisation project as part of my studies at TGA, where I had roughly 8 weeks, working halftime, to finish this project. I wanted to make something creative and interesting whilst sticking to CCC. After a bit of brainstorming I decided to make a first person shooter controller that utalises input combos to cast different abilities. I used Guilty Gear: Strive as a reference for how the input combos work and how they are represented. I worked alongside another programmer, Tim Wennerberg, who made an AI director in the same project. The project was made in Unreal and it was also a great learning experience since its my first time working with Unreal.

-- Why I Did It --

I knew from very early on that I wanted to make something in first person, mostly because I prefer how first person games feel to play compared to other genres. I had multiple options for what i could do, but since I like experimenting with and fusing different genres. I also like games that include a large moveset for their characters and weapons, but im not a big fan of how it is usually handled. In most games each new ability just gets a new key assigned to it which often leads to needing to either really stretch your hand or completely move it which easily messes up how you move your character. I also personally find it difficult to hit the correct key and not press any nearby keys at the same time.

However, I really like how fighting games handle large movesets with the use of input combos. I did realise quite quickly though, that I did not want to copy the input combo system one to one, since fighting games usually uses movement input for their combos. The impact a characters movement has greatly differs between fighting and shooter games, so I knew that I had to adjust the system for a shooter game.

I usually find myself binding as many abilities as I can to different mouse buttons since I don't fully utalise the fingers on my mouse hand normally. That lead to the conclusion that somehow using the mouse for the input combos would be optimal. I didn't have a lot to work with though since the standard for mouse inputs are left/right/middle mouse click, scroll up/down and physical movement. Even if back/forward buttons are very common, there are a lot of mice that do not include them. I thought about different ways to use the inputs but ended up settling on using the physical movement for a "virtual joystick" while temporarily pausing the normal camera movement. I decided on this because I thought it would be one of the easier methods for a player to learn aswell as allowing for a lot of varied but shorter combos. A small contributing factor was how Guilty Gear: Strive visualise their combos since it is the fighting game I have most experience with. I also decided to freeze the camera movement while inputing combos to hopefully reduce motion sickness, since it is something I sometimes struggle with.

Example moveset from Guilty Gear: strive.

-- Result --

-- System Design --

This segment highlights more of the decisions I had to make for the design of the systems and how they work.

-- Priority-Based State-Chain-Machine --

I am always looking for ways to improve my character controllers to give as satisfying of a result as possible. In this project I decided to experiment with a heavily homebrewed version of a statemachine for the weapon controller. Each ability is built up by multiple states that lay in execution order in a list so that the currently running state will tell the controller when it wants to advance in the chain.

An example of how the flow can look in a state chain.

Each state in a chain has a priority level to decide whether you are allowed to switch to a new state-chain. Since each state in a chain holds its own priority, you can easily set when each state-chain can interrupt the current one to perform animation cancels or similar strategies.

An example of how different prioritys can affect input timings. The state machine will then completely interrupt the current chain and switch to the new chain.

-- Input combo strings & State translation --

The simplest way I figured to store and access was in a form of hash map, in this case an unordered map. I used an actual string as the key since its the simplest type that can store a list of values and still be hashed by the standard C++ library. Each input value is stored as a char and is then added to the string once the cursor returns to the center of the crosshair.

Representation of each character value in the string as an integer, using accurate values from ingame.

-- How Inputing Combos Work --

The system for deciding what input the player is currently inputing has a couple of steps, and each step has different types of checks and "legal moves" you can perform. Each input symbol has its own value represented by an enum mostly since it is easier to construct the keys for the hashmap by writing the symbol and order you expect to recieve. The first step of the combo is exiting the "crosshair circle" is checking the direction the cursor exited and assigning the appropriate directional enum. The next step is to check if the cursor moves left or right, and increase the value based on the direction. The step after that is a combination of two checks. First it checks if you move the cursor back to where it came from and adds a higher value, based on the enum order, and auto completes the input symbol. The second check is to see if you continue going in the same direction around the circle and adds +1 per quarter revolution until you have made a complete circle where it auto completes the input symbol. You can also complete the input symbol manualy by entering the crosshair circle with the cursor again.

Closer step by step look of how the symbol is calculated in the backend.

-- Possible Improvements --

Even though I am content with the outcome of my project, I still think there are alot of areas and features I can improve if I decide to continue working on it. The first and probably most noticable feature is animations, it can be hard to tell whats happening when its not properly visualised but I unfortunatly didnt have time learn Unreals animation system to add any.

One thing that may not be noticeable in the video is that there are alot of potential improvements to how it feels to perform the input combos. First of it uses a toggle input to start and end the combo, I decided to just implement something simple so I could move on with the rest of the system, but I think a hold input would feel much better since it requires less inputs and gives a more tactile response to doing a special action. 

Another thing is that currently, performing a combo completely blocks all camera movement. It was a concious decision to try to minimize potential motion sickness and dizzyness but I would like to experiment with a customizeable camera speed while inputing a combo. It might help with feeling like you have more control over the character.

One thing that could improve the feel of performing multiple combos in a row is to "cache" the combo input your'e trying to perform and then switch to it whenever possible, within a reasonable time span.

An example of how it could switch state chain after the current chain is done if the priority check fails.

I could also add more abilities and make them more intricate to properly show what this system is capable of.

-- Progression --

-- Week 1 --

This week was mostly spent setting up a project in Unreal and familiarising myself with the workflow. A lot of time was taken up by various presentations but I managed to set up some basic movement controls for the player.

-- Week 2 --

During this week I started implementing basic shooting logic for projectiles and started to setup most of the back end systems for the weapon controller.

-- Week 3 & Week 4--

These weeks I started setting up the controls and system for inputing the combos. I was also working on the visual representation alongside it, mostly because it was easier to tell what was happening when I could see it. Sadly it meant that the feature as a whole took a bit longer to implement.

-- Week 5 --

Most of this week was spent implementing a dynamic HUD for representing what combo you have currently inputed. It took much more time than expected mostly because I struggled on finding a proper answer for how you can make a dynamic HUD in Unreal.

-- Week 6 --

I got sick during most of this week so I didn't make a lot of progress on the project

-- Week 7 --

During this week I finalised the input combos and fixed certain bugs with it. I also added a couple of abilities to perform to properly show the system.

-- Week 8 --

This was the final week which was mostly spent working on this portfolio website as well as presenting about my project.