#3D Platformer Edge Sliding Physics

10 messages · Page 1 of 1 (latest)

quasi valley
#

Hey, I'm making a 3d jump game and having an issue solving this. I've tried using 2 collisions and disabing 1, changing them to rectangles instead of capsules, and several other things such as using raycasts pointing down and disabling gravity near the edge.

I haven't seen ANY working fps controller online that handles crouch jumping without this slipping issue. Anyone have ideas on how I can fix this so that players can both reach higher ledges when crouch jumping, but not be subject to slipping down when they release crouch?

Note: This only happens when crouching jumping. When doing a normal crouch and releasing the player never slides off the edge. This has to do with changing and resetting the collision size & y position of the player in the animation, both of which cause a slide when reset near an edge.

https://www.youtube.com/watch?v=2z0M4nyLzWU

https://www.youtube.com/watch?v=wiZpAYfJF5I

shy elk
#

Hi there 😊,

So I presume the last video shows, that no matter from which direction you grow or shrink the collision shape, sliding is triggered? And the first video only shows one way of "edge" sliding, but you tested the same thing with a rectangle and other edge configurations, right? (Which is really odd, I'd expect a flat area of a rectangle not to be sliding on a flat top of rectangle).

First of, do you use CharcterBody3D? If so, did you fiddle with floor_snap_length or floor_max_angle, or any other properties relating to movement and sliding?

If you tried the above already or if it doesn't work:
You said you tried multiple collision shapes but did you try a capsule "ball" for the crouched (feet) size and another one for the standing (body) size, just animating the standing one and having it offset in the y-axis, so it never touches the ground? In my experiment it's important not to animate the crouch (feet) capsule "ball", but only the standing (body) capsule. Both shapes would always stay enabled.

I have a hunch, that any change to a capsule collision shapes properties retriggers "sliding" calculations on the next frame.

#

I implemented some simple wall-walking once and remember it was important to rotate around the sphere parts of the capsule or else you got "shivering" behavior, where the character was "on floor" in one frame and "in air" the other slowly falling off the wall.

The interesting thing is not the wall walk, but the collision normal I used to "press* the character to the wall. You might also leverage this to keep the character in snapping distance while the animation player is running. However this feels hacky and "parkour" gamers might probably notice it. On the other hand, it might be "fair" since one does not expect the same movement while running and jumping and standing up from a crouch. But it's worth a shot.

quasi valley
#

Hey, first off thanks for taking the time to help me out!

Yes, I completely changed the collision to a rectangle from a capsule and retested everything, and what I found was that it comes down to moving the y position or changing the size of the collision when going into standing that causes the sliding. For some reason, this doesn't happen when playing the floor specific crouch animation, probably because the callision maintains the same y position throughout (and expand upward).

Yes, characterbody3d. I didn't know about floor_snap_length or floor_max_angle, so I will test that out. Regarding having 2 collision shapes, I'm not sure there's a difference, because in the end I need to move the feet up either with y or size to allow the player to make jumps they couldn't make if they tried a normal jump (they need to clear more air)

What do you mean by rotating around the sphere parts of the capsule, and keeping them in snapping distance?

I have a zip of the project to show a minimal reproducible example, if you'd be so kind would you mind taking a look? It was taken from my project and has the same physics code and movement code that I'm using. Will send you a DM

shy elk
#

Just forget about the rotating around sphere part, it was just to illustrate nearly-at-rest bodies exhibiting weird behavior. In my sphere part cases, it was rotation. In your case it's translation, causing issues. I made my example somewhat convoluted, I guess. 😅

Yeah, I had the hunch the animation which skips y-translation will most likely be unaffected.

Are you currently animating the position of the CharacterBody3D or the CollisionShape3D itself? Can you switch them out and take a look if it helps? (I know we are fiddling around here, Godot Physics doesn't have a good track record for pin-point accuracy (yet), nor is it documented when which part of the physics / node system triggers which reevalution).

Coming back to the two capsule experiment: Maybe I don't wrap my head around the multiple translations, but shouldn't one be able to keep the "feet" capsule static in the animation and do the rest by animating just the y translation around that? So that from the perspective of the feet sphere, we are not moving once we connect with the floor again, thus not retriggering the "sliding" evaluation?

One more option you have is using godot jolt physics, as a drop-in replacement. Since it's a specialized more mature physics solution. It might also be interesting to see if the issue persists, if you decide to open a bug report.

In regards to your MRP, I'm no big fan of doing this "here" in Discord. This is more a bug report thing, with a (git)-repository where people can clone from and commit changes to. Sending zip files around is to 90s for me, sorry. 😊 It will however be appreciated on the GitHub project (I guess).

One more thing, did you try the GoldSrc character controller (you said you tried most/all, but maybe don't know this one). It's fairly elaborate try to recreate Half-Life 1 character behavior.

summer monolith
#

i dont know if this is good or common pactice. but the way i do crouch is not to adjust the collider, i just have 2 colliders. crouch sized one and standing size one and disable/enable as needed. and that red line is my "hit head" ray cast that prevent character from standing under a ceiling

#

alternatively if you want to keep doing it the way you are ide advise adjusting the local Y on your collider to keep the origina(ground touch point/bottom) on the ground at all times. but im not certain of a good way to code that and i dont think godot lets you set origin of colliders

shy elk
#

This is a good solution, but it doesn't account for the duck jump, as OP wants height gain through duck jumping. This only works if the lower collider is somehow raised. Either respective to the CharacterBody3D or the whole CharacterBody3D (via a gain in velocity or position).

Afterwards standing up from crouching issues the latest position to be reevaluated if sliding is necessary and the physics engine comes to the result it should slide, even though nothing in velocity or position changed (at least not apparent from the dev points of view).

summer monolith
# shy elk This is a good solution, but it doesn't account for the duck jump, as OP wants h...

ah yes didnt catch that part that it was hist intentions. appreciation the critiscism/catch. what could be done, is instead have the crouch collider near the top instead of root like my photo shows and when changing back you can set up a raycast that will go towards floor at a distance for bottom of crouch collider to bottom of standing colider and everytime it hits the floor it can move the player up 1 pixel, till it doesnt detect anymore then set the collision shape to standing again.

and if that code is done in a loop it would be instant.

quasi valley
#

Hey guys, I did manage to fix the issue very simply by scrapping the animation player altogether, and changing the y position to happen on the player node rather than the collision node. And ensuring the y value change is consistent so the origin is always maintained properly, and happening 100% on the same frame by removing any time component from the code. (may change later to interp them at the same time, if it doesn't break it).

@shy elk I did check out the goldsrc code and it looks great, I had no idea about that when I started. There were some bugs though but maybe that's because I just ran it with the base physics engine rather than jolt which it recommended.

@summer monolith Thanks for the suggestions, and I find your idea with the raycast pretty interesting..For now what I have below seems like the most straight forward solution.

    # floor crouch
    if Input.is_action_just_pressed("crouch"):
        crouched = true
        standing_collision_shape.shape.height = 1
        global_transform.origin.y -= 0.5
    
    if Input.is_action_just_released("crouch") and crouched:
        crouched = false
        standing_collision_shape.shape.height = 2
        global_transform.origin.y += 0.5        

    # jump crouch
    if Input.is_action_just_pressed("crouch") and !is_on_floor():
        crouched = true
        standing_collision_shape.shape.height = 1
        global_transform.origin.y += 1

    if Input.is_action_just_released("crouch") and crouched:
        crouched = false
        standing_collision_shape.shape.height = 2
        global_transform.origin.y -= 1