In this update, I looked at developing a combat mechanic. I’ll go through the initial implementation of shooting, to reworking the attack into a sword swing. I’ll also discuss how I implemented the hitboxes and special mid-air swings.
Now that movement was finished, another functionality that we discussed for the game was combat. The idea was to have enemies throughout the map, and you would have to fight them to progress. The goal of this mechanic was to make the game harder while also making it more interesting.
The first issue I encountered was the fact that in our brainstorming phase, we did not clearly define “combat”, so we did not go into any further detail apart from having enemies on the map. That meant that it was my responsibility to make a combat system that would make sense given the game’s theme / idea. I had full freedom over the mechanic, but that also meant that I had nothing to go off, which meant a lot of trial and error.
My first idea was to implement a shooting mechanic, and that’s what I did. From my last update, I learned how keybinds worked, and as such all I needed to do was to spawn a bullet and propel it forwards in the direction I was looking at when the attack key was pressed.
I started by creating an empty circle object prefab (with a 2D collider for registering hits and a Rigidbody for movement) and connecting it to a script. The script had to do 3 things – move the bullet, handle the logic behind hitting an entity and despawn after some time.
Once the bullet prefab was ready to use, I implemented the basic functionality of the bullet – on keypress, the prefab was instantiated, and its direction was set based on where the player was looking. Here I found out about directional vectors (Vector2.Left / Vector2.Right) which came in quite handy. The bullet then handled its own lifetime logic internally - it would call Destroy() on itself after some time or when the collider detected a hit with an enemy. This was simple, and it felt quite good.
However, after a sync meeting with the team, I realized that our character was supposed to use a sword, and not a gun, so my gun mechanic got unfortunately scrapped then and there. Again, I found myself on ground zero and hand to brainstorm on how the sword would work.
The quickest idea to implement a sword functionality was to draw a big circle hitbox around the character and destroy all enemies in the radius. I took this approach for the first version of the mechanic, but I quickly realized that it is indeed not realistic for the character to be hitting things behind it. It was time for some refactoring.
To fix the issue of us being able to hit things behind us, I created a square hitbox that got enabled for a few seconds after the player pressed the Attack keybind and connected it to a 2d collider. This meant that I could offset the hitbox in front of the player, and as such, kill things that were only in front of the player.
I also added a mid-air attack. The only thing it does is move the hitbox below the character if he attacks mid-air, but it makes the game feel way better considering the main theme is platforming (and hence, jumping around).
The biggest takeaway from the combat task is how important communication is while designing software. The time I spent working on the shooting mechanic could’ve been saved if we had discussed what type of combat we wanted in the game beforehand.
I also learned that melee combat differs quite a bit from ranged-based attacks. When I implemented the shooting mechanic, the bullet did all the heavy lifting. However, when I converted the functionality to use a sword, I had to fine tune a lot of things – the placement of the hitbox, how the hitbox moved depending on the player, attack timings, etc…
Finally adding a special mid-air attack reminded me that small features can add a lot to the general feel of the game. When we only had sideways swings, I felt like the combat felt unfinished when the player started combining it with jumps. Adding a downwards swing took me a few minutes to complete, but it made the game feel a lot more polished.