Code Structure
While building the character controller I worked a lot with inheritance. I created the character-based class scripts from which the player character, enemy character, and boss character all inherit from. My decision to do this was based on the scale of the project, since from the beginning I planned to create a very big project I knew that using inheritance can save me a lot of time and energy. Another factor in using Inheritance is to keep my code and project well-structured and organized. 
Character Animations
Since Elden Ring is the main idea behind this project I tried to create a character controller with a feeling as similar to the original game as possible. Animations play a crucial part in the game feel. The player character utilizes an 8-dimensional locomotion set. Allowing the player to move freely around the map but also strafe when locked onto enemies. All of the animations are sent to the server and therefore can be seen on all clients that are connected. In addition to that this project supports Mouse and Keyboard input as well as Gamepad inputs (preferred Gamepad). When playing with a Gamepad the character displays more animations depending on the move input through the joystick.
Jump / Sprint /Dodge
Besides the Locomotion of the character, the player can execute more movement commands. Pressing the Jump key makes the character go into a jump state. During that state, the player has still control over the character and he can move slightly. The player can accelerate the character with sprinting. There are currently four movement states in the game: Idle, Walking, Running, and Sprinting. The movement inputs are clamped on those values making the movement feel more snappy and reliable. There are two types of dodges in the game. If the player is not moving and is attempting to dodge then the character is doing a backstep. However, if the player is moving while attempting to dodge the character will perform a dodge roll. The dodge and sprint input share the same key binding. Pressing the key will perform a dodge, and holding the key will start the sprinting without performing a dodge. I implemented this using Unity's input system. 
​​​​​​​
The animations of the actions are on an override layer in the animator controller and are all sent to the server which makes them visible to all connected clients. All of these actions are linked to the stamina system. An action consumes stamina and cannot be performed without a sufficient amount of stamina. ​​​​​​​
Camera Controls
In this project, I decided not to use Cinemachine and rather to write my own camera controller. By doing so I have more control over my camera and also I know how my controller is working. This project was made with the intention to challenge my skills and enhance my knowledge so I thought using Cinemachine would be not the right decision. My camera controller is set up in multiple parts: the camera is on a camera rig that follows the player. The camera handles the vertical rotation and the camera rig the horizontal rotation. With this setup, it was also possible for me to add collision detection to my camera and therefore avoid clipping into walls or other objects. The player's movement direction is the camera's forward vector which means that the player can control the character's movement direction by looking into the direction he wants to go to.
A crucial feature of Souls Like games is the ability to focus on enemies. I also implemented this feature in this project. Once the player activates the lock-on mode the camera will focus first on the closest target. The player can swap between targets. If the player changes the focus to a different enemy the camera will not snap on to the closest target from the player but rather it will lock on the closest enemy that was next to the previous enemy. The lock-on state is also sent to the server so that all clients can see the strafing movement.
Character Stats
The player character has a variety of different stats such as Health, Stamina, Poise, and more. The UI elements are adjusting themselves based on their stats. If a stat increases in its max value the bar will also increase its length appropriately. This gives the player a better sense of progression throughout the game. The stamina system is used for many actions. After a few seconds of not using any stamina, the regeneration will automatically begin. It is possible for the player to go into negative stamina, if an action costs 25 stamina but the player has only 5 stamina left the action will still be executed and the stamina value will go into a negative value therefore increasing the recharge time. I implemented this to eliminate a potential point of frustration, in this way the player only needs to check if there is stamina rather than checking if there is a sufficient amount. No action will be executed once the stamina value is below zero.
Save & Load
Due to the size of the project and the content planned for the game I decided to implement a Save & Load system early in the development. All of the player data is written into a file on the local machine. It contains all the necessary information like the character's position, character stats, and character achievements such as bosses. When loading the data all of the values are applied to the world. The player is spawned at the same location as when he disconnected and with all of his attributes and stats. Bosses that were already slain by the player will not spawn in the world again. Since Unity can only write primitive data types to json files, I created my own dictionaries to store more complex data. 
Weapon System
The weapon system is one of the most important systems in a Souls-like game. I wanted to create something as in-depth as possible. The player has two hands in which he can equip one piece of equipment (at this stage in development, one sword is in each hand; improvements are planned). Every weapon has a variety of attributes to bring depth to the system. All the weapons have names, icons, descriptions, and unique item IDs. The player needs to fulfill certain stat requirements in order to wield a weapon, this adds another layer of complexity to the system, improves the variety of weapons, and the depth of the game, and gives the player the feel of having character classes. Another layer of depth is added by having different damage and armor types. To increase the complexity and feel of the blocking system I am planning to add poise to the combat. There are three types of attacks that the player can execute: Light Attacks, Heavy Attacks, and Charged Attacks. These attacks have different damage modifiers and animations. Every attack comes with a set of animations that can be chained together to further amplify the damage. 
Hit detection
To make the combat system feel as good and responsive as possible, I added hitboxes to each limb of every character rather than using one big hitbox. This not only improves the hit detection, it also allows me to spawn particles at more accurate positions and therefore add another layer of polish to the game. To make the hit detection feel good for the player all the characters in the game play a specific hit reaction animation based on the hit impact angle. 
Enemy AI
The enemies right now are a work in progress. All of the enemies are inherited from the character class, this made it easy to implement the enemies on the server side. For the behavior, the enemies logic is handled by statemachines. In the past, I used Unity's animator as a statemachine. However, in this project, I decided to write my own statemachine. I made this decision to have more flexibility in the logic. 
The enemies are currently a work in progress. I am aware of certain problems and are working towards fixes.
W.I.P.
This project is one of two projects on which I am currently working on. So far this is the biggest project that I worked on. There were a lot of challenges and things that I have newly learned, such as multiplayer in Unity and the Save/Load system. However, I was able to overcome all of these challenges so far and created a project of which I am genuinely proud. I have big plans for this game a few examples are: blocking, more weapon types (two-handed weapons, ranged weapons), armor and pieces of equipment, and more combat elements (Riposte, jump attacks). I am very excited about the rest of this project because so far I learned a lot about Unity and Game Design and I can't wait to improve even more.
Back to Top