Ledge grabbing/hanging

Hi,

I’m relatively new to unity, and am trying to build a fairly simple 3D platformer, using as a base some of the scripts that come with it.

I’ve got a character running and jumping around with animations working. What I’d like to do is have it so when he’s jumping, if he comes close to a ledge he’ll grab onto it, and hang, until you press a button to climb up or fall back down.

I’ve done this so far, on someone’s advice, using a Raycast - so I have a ray which is case from near the head of the character, about 5 pixels forward. (Near the head so that only if the character’s hands are near the platform will he grab it)

When this ray detects a collider, it sets a variable in my character move script to true, which can only be set back to false when the character hits the ground. I haven’t implemented anything for getting the player out of the hang animation yet.

The problem I’ve got is making the player hang in the right place. I’m currently using the RayCastHit (got when using Physics.Raycast) as the point where the player should move to hang from, but because the raycast can sometimes hit when it’s kind of inside the platform, it means that the player sometimes hangs inside the platform. What I think I need to do is find the x,y,z on the actual collided object, that is nearest to the x,y,a of the RaycastHit. But i have no idea how to do that.

Anyone point me in the right direction, or let me know if I’m going about ledge grabbing all wrong?

thanks a lot for reading :slight_smile:

For starters I would get familiar with the way Unity works; both interface and the scripting. Start analyzing the scripts present and understand how they work with the game objects.

If you are already understand that then far as the edge hanging I would try creating two empty game objects and position them to the hands of your character. Make those game objects children of the hand models and then use the game objects coordinates as the grips.

When your character falls off a ledge. Decide how close he is, if he is close enough that lock his hands onto a x,y,z position on the ledge… perhaps maybe initialize the rag doll to give it the effect of dangling.

Just some ideas…

1 Like

I actually tried to do it by having collision spheres on the hands of the character, but found that this way there was no way to check the coordinate at which the collision occured. Hence me using raycasts, which means I do have a coordinate for the collision.

The problem though isn’t that, it’s making that collision coordinate into a point on the mesh it collided with, so that the character can be positioned reliably, no matter where he his the object. for example, it’s possible that the collision of the ray intersects the actual object, so setting the character to that point means he in turn intersects the object, which looks wrong.

I need to find a way to find the nearest point on the actual mesh to the collision point, and then I can set the characters position to that. I think…?

You could do the classic technique and have a trigger box set up on the grabbable edge that has the coordinates you want the character to grab onto.

var grabSpot : Vector3;

function OnTriggerEnter(hit : Collider)
{
   if (hit.transform.tag == "Player") {
      hit.gameObject.SendMessage("GrabMe", grabSpot);
   }
}

The player would have a script with a function called GrabMe that places the character based on the position passed. (You could also switch that with a Transform if you wanted to position it using an empty game object)

I fixed this at last. I’ve done it by having a collider box against each edge which should be grabable, and assigning them all to a layer.

Then I test the raycast coming out of the character against only objects on that layer, and if it finds one it moves the player towards that object by doing

playerPosNew = playerPos + (distanceAlongRayUntilCollision * ledge.forward);

Puts him in the right place, no matter at what angle the collider is at. :slight_smile:

Awesome!!!

Can anyone post a working example? Like a super simple unitypackage?

I would want this to be more dynamic, but This would be a GREAT start! I’ve been avoiding this play mechanic because of the need to build the collider boxes into the level.

What this needs now is a “tentacle” object like a curb feeler that looks for ledges that are within reachable range of the character and dynamically attaches a collider box to the ledge. But only while the character is in range.

Or let the character grab any surface, but use a collider that returns the angle of the surface. If it is too steep, then slowly accelerate downward. So that the length of time the character can hold on is proportional to the angle of the ledge/surface…

I love this place!

BUMP! I wanted to do this and im surprised to not see more information on the topic! I am attempting to use a box collider as a trigger. Now I assume that I would have to make a function that would change the character’s animation into a hanging animation and keep the character “hang” there. I’m a novice in coding in Unity, but have some prior scripting experience. Could I get an example of this?