I struggled to do something similar and finally got it.
In mine, I wanted to be able to jump onto and off of the ladder but also be able to jump through the ladder or hit jump from the bottom. The in-class code was causing problems.
In my code, I created a bool that told me if the player was attached to the ladder (be sure to declare that variable as false at the top of your script, not pictured here). A player becomes attached by hitting the up or down button (Vertical axis). If your player is attached, then your gravity scale is set to zero. Once it becomes detached (bool goes false), gravity is set back to normal. I also made set the bool back to zero if the player jumps.
Hope this helps someone!
private void PlayerClimb()
{
if (myFeetCollider2D.IsTouchingLayers(LayerMask.GetMask("Ladder")) && Input.GetAxis("Vertical") != 0)
{
isAttachedToLadder = true; // Lets us know that the player has attached to ladder.
float controlThrow = Input.GetAxis("Vertical");
Vector2 climbVelocity = new Vector2(myRigidBody.velocity.x, (controlThrow * climbSpeed));
myRigidBody.velocity = climbVelocity;
myRigidBody.gravityScale = 0f;
bool playerHasVerticalSpeed = Mathf.Abs(myRigidBody.velocity.y) > Mathf.Epsilon;
myAnimator.SetBool("isClimbing", playerHasVerticalSpeed); // Lets us know if the player is actually climbing.
}
else if(isAttachedToLadder && myFeetCollider2D.IsTouchingLayers(LayerMask.GetMask("Ladder")))
{
myRigidBody.gravityScale = 0f; // If player attached but not climbing, we still have 0 gravity.
}
else
{
myAnimator.SetBool("isClimbing", false);
myRigidBody.gravityScale = startingGravity;
return;
}
}
private void PlayerJump()
{
if (myFeetCollider2D.IsTouchingLayers(LayerMask.GetMask("Ground", "Ladder")) && Input.GetButtonDown("Jump"))
{
isAttachedToLadder = false; // If player attempts to jump, they detach themselves from ladder.
Vector2 jumpVelocityToAdd = new Vector2(0f, jumpSpeed);
myRigidBody.velocity += jumpVelocityToAdd;
}
}