Daily Progress: Ladder Challenge
Today is more of a process sharing approach than a tutorial, most of the techniques we’ve learned in the ledge grab so expect a lot of familiar techniques! First, I’ve headed down to Mixamo to see what’s available in terms of animations and there’s a couple I’ll be using: Climbing Ladder, and Climbing To Top.
After duplicating the animations and placing them into the players Animator tree, I made two new parameters; A boolean called ClimbingLadder, and a trigger called ClimbLadderToTop.
The transitions would be:
Idle to climbing ladder:
ClimbLadder = true.
And ClimbLadderToTop transition:
ClimbLadder = true
Next, I downloaded a ladder asset from GameDevHQ and placed it into the scene. I did have to scale it up a bit. Later, I duplicated the pieces inside to double the rungs.
After that, I created a cube and placed it at the bottom and called it Ladder_Checker.
I ticked off the Mesh renderer to turn off the cube object, and ticked trigger in the box collider as we’ll be using OnTriggerEnter and we’ll be checking for the players Stair collider. We’ll need to attach a rigidbody to the cube as well to make the trigger collision work. Make sure Gravity is ticked off and Kinematic ticked on. I did the same for the player except call it Ladder_Enter_Checker. and added a new tag, “LadderEnterChecker” as well.
Attach a new script called LadderChecker to the Ladder_Checker_Cube, let’s begin by checking for the collision in the OnTriggerStay method.
Great! On to the next step! No pun intended… :D
I shrunk the ledge collider on the Ladder_Checker so that the climbing animation will always be approximately in the correct spot. Then I added the Key check to see if the player is pressing up while near the ladder:
So once we know the player is pressing up inside of the ladder zone, we’re going to do the same things we did as the ledge-climb and access the parent of the ladder-checker which is the Player to access the currently unwritten ClimbLadder method.
In the player script, we’ll write our ClimbLadder method. We’ll set the boolean to true so unity knows to activate the ClimbLadder animation, and set the speed to 0. We’ll also create a new boolean called _climbingLadder and set it to true here. We’ll use that boolean in the CheckController function:
It looks a bit long and convoluted, but basically we’re now going to check if _climbingLadder is true, and if it is, we’re checking whether the player is pressing up or down using the W/S or Up/Down arrow keys and playing the climbing animation or stopping it when the player lifts the finger off the key.
Ok, I think we’ll check on the status of our ladder climbing:
Looking Awesome! Now to move our player up and down! But first let’s move all of that movement code into a new function, CheckOnLadder()
We’ll also reproduce the horizontal controls but this time, vertically of course.
There’s still the issue of gravity, so let’s go back to our regular controller code and put in a check.
If we’re climbing the ladder, we’re not going to update y which essentially turns off gravity.
Great! Everything is working as it should! We’re in the final stretch and that’s adding a check for when the player reaches the top.
There were a few issues I had to fix here before continuing. I seemed to have broken the regular control system! I first removed the _controller.Move line, it was redundant as the checkMovement would take care of it.
I then needed a system to jump off the ladder in case the player wants to stop climbing. First I created a transition from climbing to jumping:
I made a new trigger called ‘JumpOffLadder’, and a couple more parameters would need to be set, climbingLadder to false, and jump to true.
Then in the climbing function:
All of these animator settings must be changed for mecanim to trigger the animation per our transition rules. I also set _climbingLadder to false to give control back to our regular horizontal controller, and give the yVelocity jumpHeight to actually have our charcter jump a bit.
A couple more important things!
I needed to set the animation jumping to false once the player hits the ground again for things to be normal:
I wrapped the entire CheckOnLadder code with if(_climbingLadder == true); Just to be sure those controls would only be called when climbing the ladder.
Ok! We’ve given the player a way to escape if they change their minds.
Fixing the initial climbing animation
I wasn’t really liking how the player would move halfway up the ladder when they initially pressed up. Thankfully, mecanim offered a fix in the Animation clip options in the root transform position. I changed the offset from 0 to 1.2 and that fixed the initial climbing on animation pretty well!
Likewise, changing the animation speed also made it so the character would put their hands a little closer to the rungs.
Now for checking the top, I figured I’d use the same ledge_grab_checker the player has. In the Ladder, I made a new cube called ClimbTopChecker, turned off the mesh, and ticked trigger for the box collider.
Now we make a script for the ClimbTopChecker and on the onTriggerEnter, we trigger the climbTop animation to play. Don’t forget the rigidbody with gravity ticked off and kinematic ticked on!
A few more things:
I changed the ClimbLadderToTop from a trigger to a boolean. Not much of a change, but it did seem to help a situation where the player got stuck after playing the ClimbToTop animation. I also had to change a few transitions:
ClimbingLadder_anim -> ClimbingLadderToTop:
ClimbingLadder : false, ClimbingLadderToTop: True
ClimbingLadderToTop -> Idle:
ClimbingLadderToTop: true, ClimbingLadder: false.
To say Mecanim is finicky for things to work is an understatement. I spent many minutes trying to figure out the right combination of options after the initial one I thought would work didn’t!
After the player enters the top checker collider, we set the boolean ClimbLadderToTop to false to tell mecanim that we no longer need that animation and to move on to the idle state. We turn the controller back on, and like the LedgeGrab, we move the players transform over a little because the animation only moves the character, not the player so we need to play a bit of a magicians trick and replace the animation with the player once the animation is over.
And here we have it! A working ladder system! Hope you enjoyed the trip in spite of it being a long one!