Improving Climbing System

Hi all,

I moved my climbing sytem away from triggerbox detection to raycasting.

Currently I have an issue that the charakter is sometimes looking away from the edge, which he is supposed to grab. Also the hit.point is not optimal.

I’m sharing here my small system and I would be really glad to see some improvement suggestions.

function CheckForLedge() {
    var hit : RaycastHit;    
    
    var player : int = 11;
    var enemy : int = 12;
    var vegetation : int = 21; 
    var layermask : int = ~((1<<player) | (1<<enemy) | (1<<vegetation));

    if(Physics.Raycast(climb2Pos.position, myTransform.up, hit, 1.0, layermask)){
     //something is above us but but we are too far under the roof
    } else {
     //if nothing is hindering us to grab
        var alignToEdge : Vector3;
        var rotationToEdge : Quaternion;
    
        if(Physics.SphereCast(climb3Pos.position, 0.2, myTransform.up, hit, 0.8, layermask)){
           //something above us to grab
            myTransform.position = hit.point;
            myTransform.position.y = hit.point.y - 2.2;

            alignToEdge = hit.normal; //Get normal of hitnormal and ignore y - axis;
            alignToEdge.y = 0;
            
            rotationToEdge = Quaternion.LookRotation(alignToEdge);
            
            myTransform.rotation = rotationToEdge;
            myTransform.rotation.x = 0;
            myTransform.rotation.z = 0;
            //myTransform.Rotate(Vector3.up * 180);
        
            GrabEdge();
            myTransform.position = hit.point;
            myTransform.position.y = hit.point.y - 2.2;
            return;
        }
            
        if(Physics.SphereCast(climbPos.position, 0.2, myTransform.forward, hit, 1.0, layermask)) {
            //there is still wall. can't climb
            Debug.Log("Can't climb");
        } else {

            if(Physics.SphereCast(climb3Pos.position, 0.2, myTransform.forward, hit, 0.9, layermask)){
                Debug.Log("Found something to climb");

                
                Debug.DrawRay (climb3Pos.position, myTransform.forward, Color.red, 2.0);

                myTransform.position = hit.point;
                myTransform.position.y = hit.point.y - 2.2;
                                
                alignToEdge = hit.normal; //Get normal of hitnormal and ignore y - axis;
                alignToEdge.y = 0;
        
                rotationToEdge = Quaternion.LookRotation(alignToEdge);
            
                myTransform.rotation = rotationToEdge;
                myTransform.rotation.x = 0;
                myTransform.rotation.z = 0;
                myTransform.Rotate(Vector3.up * 180);
        
                
                GrabEdge();
                
                myTransform.position = hit.point;
                myTransform.position.y = hit.point.y - 2.2;
            }
        }
    }
}

And here is the setup for the climbPositions:

1598841--96347--$climbingPic.jpg

Saw your PM, and now that i look at your code, it uses a surface normal to calculate the surface your character/ninja is meant to grab. (at least that is what it looks like…) since a normal points backwards to your characters direction, try reversing the direction he climbs - this might fix the “facing wrong direction” glitch.

BTW, you are using a Quaternion to spin the character around to face the ledge. personally, i would use transform.LookAt like this:

direction (whatever that might be) = transform.LookAt(Vector3(<your surface normal variable's x axis>, 0, <your surface normal z axis>);

There you go. my two cents for now.