Personal Project
For four weeks I worked on a small personal game with a specific focus on networking, latency compensation and movement. I made my own custom character controller with Titanfall-style movement and velocity management, with wallrunning and doublejumping.
This project was made in Unity 6 using C# and their DOTS Netcode for Entities system.
Local Room Based Matchmaking System
When booting up the game, the user is presented with two options. Open a room or join a room. If the user opens a room, they will be put into the game while their room is broadcast to all other users on the network over UDP.
Another user can then through the main menu see a list of all rooms that are being broadcast, updating in real time. They can then choose to connect to a room, which will connect the room host and the user and they will now be able to play together.
Player Controller
Since I wanted complete control over the movement and behaviour of the character, I opted for manually creating my own controller from scratch. I implemented custom collision handling using Unity's Physics package, utilising their Capsule Sweep and Overlap Sphere functions, for the movement and ground collision respectively of my player.
When the player stands on floors that are angled, their movement is correctly transformed to lie along this angled plane. However, if the angle gets too great, the player instead loses control and slides off of the surface.
With a custom implementation of movement, velocity management, slope handling and step height, I could create exactly the type of behaviour necessary for my game and make sure that it worked flawlessly even at very high latencies using client-side prediction.
Wallrunning
As the core of the game, I focused heavily on making this feel as intuitive and natural as possible to the player.
Whether or not the player is allowed to run along a wall is decided by a couple of rules. These rules being if the player is airborne, if a sphere around the player is overlapping a wall, if the players current velocity is high enough, the time since they last ran on a wall and their viewing angle relative to the direction they are travelling.
When wallrunning, the players inputs and resulting velocities are transformed to lie along the plane of the walls normal. Any velocity going into the wall is nullified, and a part of the velocity going out from the wall is instead transformed along the wall to give the wallrunning some "stickiness".
If the player is travelling along a circular wall such as a cylinder, the angle between the players previously known normal and their current normal is applied to them as a rotation. This allows the player to naturally travel and flow around round objects.
Double Jumping
To provide the player with a sense of complete control of their own airborne state while also not being difficult to use, I implemented a special form of in-air jumping.
When the player is in the air, they have the option to jump once, providing a small vertical boost and allowing for longer jumps. With the small amount of general air control and generally high velocities that the player has, however, I also decided to let this doublejump act as a form of air brake or instantaneous velocity change.
If the player decides to jump forwards, it simply acts as a simple burst of vertical velocity. If, however, the player decides to jump diagonally, the doublejump consumes a set amount of velocity from the player and transfers it towards the desired movement direction to provide a quick burst of air control.
Doublejumping will always consume the same amount of velocity if possible, but depending on the desired direction of the jumps angle to the players current velocity, how much of this consumed velocity is transferred changes. For example, if the player decides to doublejump backwards, roughly half of the consumed velocity is moved in order to act as a form of brake.