Project Info - Annihilis

Annihilis is a Quake-style shooter made in the Unity Engine. Designed and programmed (C#) by me as a solo project, the game features a custom made movement system that handles jumping, dashing, walking up slopes, and knockback from enemies and explosions. The movement is heavily refined to feel fast, fluid, and satisfying, almost as if the player were gliding through reality.

A playable demo of Annihilis can be found on my Itch page. You can also view this project's source code on my Github.

Scripting

Main Takeaways

Character Collision

Initially, the character's collision consisted of a single capsule collider. The character movement relied on the force of friction to stop the character when the player let go of the controls, so I made a physics material just for the player character so that I could adjust their friction easily.

bodyCollider

However, I quickly ran into a problem in testing: If the player character touched a wall, they would stick to it even if just brushing against it. Merely tapping a wall was enough to stop the player dead in their tracks.

My solution to this issue was to split the player collision into two separate colliders. I kept the capsule collider and reduced its friction to 0 so that the player no longer stuck to walls. I then attached a second sphere collider to the player and positioned it at the bottom of the capsule collider. This collider would act as the player's "feet" and receive its own physics material which would have friction.

playerCollision

(The pink ball is just so I know where the player is at when they aren't selected since the player has no model)

Moving Up Slopes

The player character moves by having acceleration applied to them in a horizontal direction. This becomes an issue when the player is trying to move up a slope, which requires that the player also moves in a vertical direction to not lose speed moving "against" the slope. It also means trying to walk down a slope would only end in the player becoming airborne instead of walking properly downward.

I solve this problem by applying a bit of vector math. I need to pitch the player's velocity up or down the sloped surface which they are walking on so that the velocity is parallel with the slope. To do this, I need two things: The angle that the slope lifts off of the ground and the axis around which the player's velocity will be pitched up or down. If we imagine the sloped surface as the spoke to a wheel, the axis value would be a vector representing the wheel's "axle".

slopeDiagram

Both of these values can be derived from the slope's normal. Whenever the player touches a new surface, the normal of that surface is recorded by the PlayerController script. The angle between the surface normal and the world's up vector gives the angle that the surface is sloped off from the ground. To get the surface's "axle", we flatten the normal by projecting it onto the x/z plane (for reference, y is "up" in Unity). This gives a vector pointed along the direction that the surface is sloped in, which we can rotate into being the axle. By negating the flattened vector's z value before swapping its x and z values, we can rotate the vector 90 degrees counterclockwise and obtain the "axle" vector.

slopeCalculations

The final rotation applied to the player's velocity is made by rotating around the slope's axle an amount of degrees equal to the slope's angle. This rotation comes in the form of a Quaternion, which can be multiplied by a vector to rotate it, the vector in this case being the player's movement direction.

velocityRotation