Hey everyone,
If you’re on lecture 85: Climb That Ladder and you’re really itching to add functionality to jump off of ladders, this is how I implemented it into my game. I know someone else already asked a question about this but they weren’t able to get it working, and there was another person who implemented this but did it with their own advanced system that doesn’t follow rick’s tutorials. So I came back to this project after finishing the course to add a few things and wanted to help out anyone else looking to do the same.
Firstly I created a new bool called hasJumpedWhileTouchingLadder which starts out as false.
bool hasJumpedWhileTouchingLadder;
Then I modified the OnJump() function, which is only called once when the player hits the spacebar.
-
myFeetCollider2D.IsTouchingLayers() accepts multiple layer indexes, which can be returned by just adding more elements to LayerMask.GetMask()'s list parameter.
-
The check for whether or not hasJumpedWhileTouchingLadder is false is to stop the player from being able to jump indefinitely as long as they’re touching a ladder. Instead they will only be able to jump after coming to a full stop (which is implemented in ClimbLadder() later on).
-
I add the velocity to make the player jump as normal, regardless of it its touching the ground or a ladder. But if it is touching a ladder, then hasJumpedWhileTouchingLadder becomes true.
void OnJump(InputValue value)
{
if (value.isPressed
&& isAlive
&& myFeetCollider2D.IsTouchingLayers(LayerMask.GetMask("Ground", "Climbable Objects"))
&& hasJumpedWhileTouchingLadder == false)
{
myRigidbody2D.velocity += new Vector2 (0f, jumpSpeed);
if (myFeetCollider2D.IsTouchingLayers(LayerMask.GetMask("Climbable Objects")))
{
hasJumpedWhileTouchingLadder = true;
}
}
}
Finally, I modified the ClimbLadder() function, which is called every single frame in Update().
-
The three possible scenarios that have to be accounted for include touching the ladder without jumping, touching the ladder while jumping, and not touching the ladder at all regardless of whether or not the player is jumping. This can be achieved by modifying the if statement to include a check for
hasJumpedWhileTouchingLadder == false
, adding an else if () statement that checks if the player is touching the ladder ANDhasJumpedWhileTouchingLadder == true
, and keeping the else statement at the end as a catch-all. -
Depending on the scenario, I needed to change the player’s gravity scale. If you add y velocity to the player as I did while the gravity scale is zero, the player won’t move.
-
When touching the ladder and not jumping the gravity remains at zero. But as soon as you jump the gravity returns to the same scale as when on the ground so that the jump behaves the same. I also added an if () statement that would check if the player’s velocity is greater than zero before setting the gravity. This is so that the gravity only stays at 5 for the duration of the jump. Otherwise, my else statement would set hasJumpedWHileTouchingLadder to false, effectively resetting the ladder jump mechanic.
-
Finally if the player isn’t touching the ladder at all then the gravity should be set to the same scale as when on the ground.
-
The final statement that sets the isClimbing animation to false isn’t needed but I added it anyway for thoroughness.
void ClimbLadder()
{
if ((myFeetCollider2D.IsTouchingLayers(LayerMask.GetMask("Climbable Objects"))
|| myBodyCollider2D.IsTouchingLayers(LayerMask.GetMask("Climbable Objects")))
&& hasJumpedWhileTouchingLadder == false)
{
Vector2 climbVelocity = new Vector2 (myRigidbody2D.velocity.x, moveInput.y * climbSpeed);
myRigidbody2D.velocity = climbVelocity;
myRigidbody2D.gravityScale = 0f;
bool isClimbing = Mathf.Abs(myRigidbody2D.velocity.y) > Mathf.Epsilon;
myAnimator.SetBool("isClimbing", isClimbing);
}
else if (myFeetCollider2D.IsTouchingLayers(LayerMask.GetMask("Climbable Objects"))
&& hasJumpedWhileTouchingLadder == true)
{
if (myRigidbody2D.velocity.y > 0)
{
myRigidbody2D.gravityScale = gravityScaleAtStart;
}
else
{
hasJumpedWhileTouchingLadder = false;
}
myAnimator.SetBool("isClimbing", false);
}
else
{
myRigidbody2D.gravityScale = gravityScaleAtStart;
myAnimator.SetBool("isClimbing", false);
}
}
So yeah, that’s how I approached ladder jumping in Tilevania. I only just finished this course so I’m still very new to unity and C#. I’m sure I made some questionable formatting decisions or could have done this a much simpler way, but I’m happy that I was able to figure this out on my own with the skills that I already have from this course. I’d love to hear your guys’ thoughts on this and any recommendations on what I need to improve.
Thank you for reading.