This looks so beautiful!
Ladders were an unexpected challenge.
At first, I thought I could just change the slope limit value of the unity character controller to 90 while my character is in a trigger area that I labeled "ladder". So I would temporarily give my character the ability to walk up walls while he's in a "ladder zone". This worked fine, it turns out, for a ladder sloped precisely 77 degrees. But then I started making longer, more vertical ladders, and the seams of this hack showed. The character would go slower up steeper ladders. Makes sense. In this naive hack, ladders are steep inclined planes, the simple machine that converts horizontal momentum into vertical. The more horizontal momentum you spend ramming into a steep incline, the less momentum is left over for pushing you vertically up that incline. Also, going down the ladder facing either out or in would introduce unpleasant stepping as you were constantly exiting and reentering the trigger area. You would leave the ladder's influence, only to have gravity take over and land you back on the ladder a little lower. Over and over, all the way down. Similar to the slope stepping problem I had before.
So how to smoothly, consistently, and intuitively move my character up or down a ladder? I needed the trigger area, but not just to increase the slope limit. Ladder zone needed to trigger a whole new navigation mode based on the local space of the ladder itself. On regular ground, the up cursor means forward and the down arrow means backward. And "forward" is whatever direction you're facing. Of course! But on a ladder, up arrow temporarily means up the ladder and down arrow means down it. Unless you're at the top of a ladder facing away from it and toward the ground wishing to go down, in which case up is down! Unless again you're in the middle of the ladder looking off to one side or the other in which case up is not down or up the ladder, but forward again. Bother.
To take care of "smoothly" and "consistently" I needed to switch navigation to the local space of the ladder. And to take care of "intuitively" I used a couple dot products to check where the character is facing and most likely expecting to go. Here is my code: