Create scripts to climb a ladder

I’m inexperienced and I’m trying to understand the mechanism for using a ladder with my character or climbing over small walls. To move I use a rigidbody not kinematic, but with AddForce. I tried to create an object to simulate a ladder to climb on. To get my caracter into contact with the ladder I inserted a collider trigger on the ladder and called the OnTriggerStay function. After working a bit, my character now with a bool when he’s close enough, he can go up or down the ladder but I don’t understand something things. First of all, the script is better to put it on the character or create one on the scale?
The second thing is once you get to the top how to insert a function correctly and make my character complete the climb, making it arrive above the object where the staircase is located. Do I have to get to the top, destroy the game object and respawn at a point just above the ladder? … what is the best way in these cases?

 private Rigidbody rb;
public bool ladderClimb = false;
void Start()
     {
      rb = GetComponent<Rigidbody>();
     }
  void Update()
     {
      if(ladderClimb){
directionRot = new Vector3(0, 0, 0);  //direction of rotation
movement = new Vector3(0, Input.GetAxisRaw("Vertical"), 0).normalized; //object movement
   rb.useGravity = false;}
    else rb.useGravity = true;
}
     void OnTriggerStay(Collider collider){
      if(collider.gameObject.tag == "ladder"){
      if(Input.GetKeyUp(KeyCode.E)) ladderClimb = !ladderClimb;}}
void OnTriggerExit(Collider collider){
    if(collider.gameObject.tag == "ladder") ladderClimb = false;}

I would like that at the top of the ladder a function was activated that brings the Player just above the ladder, but I don’t know what script to use.
Maybe i can only use an animation, but how to make the animation fit perfectly, with the player’s hands resting right on the surface at the top of the stairs …? I’m confused about the methods to use.

1 Like

As a disclaimer, I’ve not come across this issue, but I understand why it’s tricky. Just as a side note though, usually there’s no one way to go about this, and what you do depends on the ‘importance’ of the animation and how realistic you want it to look.

If you want it to be perfect, then I’d suggest having 3 separate animations - one for getting on the ladder, one for climbing, and one for getting off the ladder. I would probably give the ladder 2 different (small) trigger colliders (top and bottom) with 3 bools.

isNearLadder (1st trigger) would allow the player to click to initiate the ‘get on ladder’ animation. (If the player is already isOnLadder then you could reverse the animation).

isOnLadder would allow the character to move up and down. When doing so, the ‘ladder climbing’ animation would play. You can check for up and down vector and reverse the animation if going down. At some point you’ll hit the top or bottom trigger and then it would transition in the ‘get on or off ladder’ animation. isOnLadder would turn false.

isNearTop (2nd trigger) would allow the character to initiate the ‘on top ladder’ animation. (If the player isOnLadder, else it would reverse the animation and you can go down the ladder).

In general for the animations, ‘get on and off ladder’ animations would be SetTrigger and would not transition into the ‘ladder climbing’ SetBool animation until you move up and down.

I try not to use OnTriggerStay because it’s not that great with performance. I also don’t see a real use for it as you can just set a bool to true when on the ladder and turn it off when you hit the trigger on the bottom, or top. I’m also not entirely sure why you’d use AddForce, unless you want the player to go faster down the ladder. (Maybe you could attach a script to the ‘ladder climbing’ animation and put your code in there so the animation matches more or less the velocity.)


If the ladder climbing animation isn’t that important, then you can just have it make a sudden transform.position change above the ladder top. So if the character is climbing and hits the top collider, you can just calculate a small distance above that collider, make a special effect on your character so the jump cut doesn’t look that bad, and set the animation back to ‘character’ idle. (Same for when starting to climb)

But I’d put the script on the ladder.

I hope that helps :slight_smile: If not, let me know :stuck_out_tongue:

THANKS A LOT !!!, I will try both suggestions. On the second method, could you give me an example on how to make a script for calculate a distance above the collider to get the player over the wall where the ladder is?

At first glance it occurs to me to use Vector3.Lerp to bring transform.position from top of the scale to just above this, but how do I indicate a position just above the ladder? should I use a trasfrom just above the ladder?

So it will depend on the where you place your collider. I think that will be the best way. I wouldn’t worry about Lerping because it will look weird being in the ‘idle’ or ‘climbing’ animation when moving to the new position.

Maybe something like this. It’d probably be better to have to child objects to the ladder for the colliders, unless you make the colliders a public variable and you decide to drag them into the inspector.

Untested Code

private Vector3 colPos;
private Vector3 characterPos;
private BoxCollider boxCol;
private Animator anim; 

private Start()
{
boxCol = GetComponent<BoxCollider>();
colPos = transform.TransformPoint(boxCol.center) //puts the collider position into world space
anim = GetComponent<Animator>();
}

private void Update()
{
if(isClimbReady)
{
if(Input.GetKeyDown(KeyCode.DownArrow))
{
isClimbReady = false; 
isClimbing = true; 
anim.SetBool("isClimbingAnim", true); 

}
}

}

private void OnTriggerEnter(Collider col)
{
if(col.CompareTag("Player"))
{
if(isClimbing)
{
anim.SetBool("isIdle", true);
col.transform.position = colPos + Vector3.up * 0.2f; 
GameObject newFx = Instantiate(fx, col.transform.position, Quaternion.Identity); 

}
else
{
isClimbReady = true;
}

}
}