FPS based on Unity’s FPS Controller Part 6 - Ledge climbing, damage fix, Tags class
3 minute read
My next goal was the implementation of ledge climbing to make movement around the level more fluid. I made some fixes to previous code and created a tag management class as well.
In the past few years ledge grabbing and climbing is a must in most of the FPS games so I wanted to create something similar in my prototype. There are many ways to implement climbing in a first person shooter. I had decided to do it via these steps:
Check if conditions are valid for climbing
Disable character controller
Switch to a separate “cinematic camera”
Animate cinematic camera
Move player to the cinematic cam’s new position
Enable character controller and enable main camera again
Climbing logic is divided between two classes: ClimbController attached to FPSController and CinematicCamManager attached to the new cinematic camera. By default the to other cams - main camera and gun camera - have a bigger depth than cinematic cam (which is also disabled when the player is not climbing).
ClimbController checks for valid climbing conditions every time the Character Controller collides with something else. To be able to climb the character controller has to be in the air, colliding with its sides and hitting an object which has a Climbable tag. The collision angle has to be within 30 degrees to the left or right from the current forward vector of the player. To disable climbing if the movement of the camera is obstructed (e.g. something above the head of the player), an overlap box - slightly translated towards the forward vector and translated above the player’s head - is used to detect that nothing intersects the path of climbing and the player’s head level is above the edge of climbable object. The following image shows a case of climbing obstruction - I used a gizmo to display the overlay box in red.
Invalid climbing scenario - box above player’s head
Here’s the code of ClimbController:
If the conditions are all right, CinematicCamManager’s TriggerClimbUpAnimation() method is invoked. This resets the main cam rotation, disables the gun camera (otherwise some awkward gun movements and camera angles may occur during the climb animation), disables the character controller and enables the cinematic cam. The animation called “ClimbUp” is triggered after that. This essentially tilts the cam left, right and forward while it’s also moving up and forward creating the illusion of climbing up on the side of the object.
The animation has an event which invokes MoveCharacterToCinematicPosition(). This moves the controller to the cam’s position (surprise), disables cinematic cam and enables gun cam then enables the controller itself.
Some minor changes on the code included replacing SendMessage() in Weapon with an explicit call to target HealthManager’s Damage() method (this might be more efficient) and the creation of a Tags class which is essentially a collection of public bools (currently only one - climbable) to enable tagging of GameObjects. I am aware that Unity has its own tagging system but it only lets you use one tag per object and I find that limiting.