Get the highest vertex world position on a face (ledge hanging)

I’ve been optimizing my ledge hang in my project and I had a few ideas to handle the ledge positioning. I think I’ll include a picture to make it easier to understand.


I

That’s how I want to position my player on the ledge. The way I’m doing this current is using an empty I place at the height of the ledge. I use its z position to set my player’s z position. This solution is horrible though. It requires more setup and its not flexible. Not all ledges are perfectly flat.

So I’ve been thinking. Using the rayCast method on KX_GameObjects actually returns information on the polygon it’s hitting (or at least that’s what I understand from its API documentation). So I’ve been thinking that using this information would allow me to get the position of the highest vertex’s world position. So instead of using an empty as a Z-position reference, I’d use the vertex’s world position as the Z-position reference.

I actually don’t know how to do this, and I don’t even know whether it’s possible but can someone help me out with this?
Is there a better way to get the Z-position of the ledge?

Thanks.

I was actually just thinking about this for a 2D project of mine, and my thoughts pretty much mirrored yours. I was thinking about placing an object on all ‘climbable’ ledges, but that would be too much work, especially since I’m working with tiles. Basically, my thought was that I could cast a downward ray from the player’s position + a little bit upwards and over from the direction he’s facing. If the ray collides with a polygon, then rounding that off would give me the center of the polygon and tile. From there, offsetting the player would be easy.

For your project, since you’re not working with tiles, or evenly spaced polygons, you might want to cast a couple of rays, but the principle probably would be the same. One would be straight down from the player’s position plus up and over in the direction he’s facing. That returned position should be pretty much where the player’s head should line up. Another ray cast in the forward direction would tell you how far to the wall the player should be. This second ray’s not necessary if your level aligns on a grid (I think).

I’ll see if I can create an example.

Wow. So far it’s working beautifully. This basically makes ledge hang super flexible!! I used to actually make a plane object and wrap it around ledges that were “climbable”. I don’t need that now; all I do need to do is check whether the ledge is in reach (using the ray).
Perfect, I was thinking about this too hard. Thanks.

I made an example anyway, hah. Mine sometimes has problems with rotated ledges where the character will slide along the ledge slowly. But yeah, it’s not as complex as I would’ve thought a couple of years ago…

And no problem.

Really? My setup works perfectly, maybe it’s because I find the delta between the ledge object and the ledge position just once. Then using that, I set the position of the player every frame to this same position, and make sure that its velocity on the Z-axis is 0. If I need to move the player, I’d just alter the delta.

It’s really cool now because now I can make a ledge object anywhere without having to worry about properly setting it up; the player does everything. Not only that, but the way everything is functioning, my character can climb anything that is reachable, including small steps at his feet, blocks half his height, walls as tall has him, and anything in between.

I was thinking. Do you actually need a ledge object? If you would be casting down a ray from virtually where the characters hands would be when reaching for the ledge, then you would detect the Z-position you want, I would think. Never tried it, but this would be the easiest sollution, I think.

When I say ledge object, I mean the block (the thing you actually grab), so yes, that’s exactly what I’m doing! d:

@ Linkxgl: oh I misunderstood. But I wonder, if you would be raycasting the poly in front of the player and get it’s highest vertex, would this also give a good result with a (left-to-right) slope? What I mean is this:

I’m sure it’s fine, the ray I’m casting is actually pretty short. Not only that, I also check the angle of the normal to the player’s local y-axis, if that angle is too large, the player isn’t able to grab the ledge. For more flexibility, I send out 3 rays, one near the feet, one near the waist and one near the head (The head ray takes priority over the rest, then the waist, then the feet). If ray 1 isn’t able to catch the ledge (angle is too large, or ledge is too far), then ray 2 does the same check, and so on. In other words, I make sure that the ledge is in reach before going into the ledge hang state. :stuck_out_tongue:

Thanks for your comments. It helps me thinking about the subject, as I’m almost there to begin programming a ledge hang myself.

Personally, I think you could suffice by realigning the whole character to the normal and then measure the scale of the normal on the z axis. Then, position the player on the very location that is basically z scale/2 + normal.worldPosition. You can realign the character to the x and y axis also. If I am vague, I could explain a bit more what I mean.

Could you explain a little bit more?