Recently I tried updating the Unreal Character so that it could freely climb on blocks. Many modern video games allow for climbing along specific ledges or handholds, but I wanted the character to climb along walls and blocks placed in various (some might say absurd) positions. I also wanted the character to do stuff in a reasonable way: climbing around corners, going over ledges, etc.
I fiddled with several methods to find and “attach” to nearby climbing walls but most of them were unreliable and/or kind of twitchy. When I found one that works pretty well I thought I would write it up here as a summary/reminder.
I first tried out several methods that involved multiple ray casts, combining normals, and odd custom collision channels. Finally I settled on a single ‘climbable’ channel which is blocked by objects that are climbable. I also decided to use a swept capsule for the collision test since this is what the character object uses anyway. Unfortunately the default swept capsule test only lets you sweep vertical capsules (!!) so I cobbled up a quick version that allowed for capsules of any orientation instead.
The steps below show a 2D capsule colliding with a rectangle, but the algorithm works in 3D as well. I’ll use 2D here because it’s easier to draw.
Let’s start with the character floating in space near a climbing wall. The character is facing the corner but is not flush against it. We need to move the character toward the floating wall and rotate them up flush against the wall.
First we project the capsule forward to see if there is anything there. If there isn’t anything there that means we’re floating in space and aren’t climbing. If there IS something there we should proceed with the climbing algorithm.
The projection collided with something. Where is the collision? We look at the position of the collision point.
Based on the collision location we rotate the capsule away from the collision point. You can do this with some vector math. The rotation is by a small amount; if the rotation is too far the character can jitter in weird cases.
Repeat the projection and rotation several times. This will gradually move the avatar to be flush with the climbing surface, even for rough or uneven surfaces.
There are some other caveats:
- If the climbing wall is mostly horizontal then the player switches back to walking. This handles climbing over ledges.
- It’s easy for the algorithm to rotate the character upside down in some situations. So there needs to be some extra code to rotate the character toward the ‘upright’ position.
- If the character is too close the wall the capsule sweep will generate an overlap instead of a hit. In this case the collision test returns a depenetration vector which is used to push the character slightly away from the wall.