• Advertisement
Sign in to follow this  

How to climb slope with speculative contacts

This topic is 785 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am using speculative contacts for my platformer physics and it works great, but there is a small thing which bugs me a lot.
When i climb up a 45 degrees slope the body slides down due to gravity - which is totally fine, but i want to have the ability to climb up the slope without any sliding at all.
 
I tried disabling the gravity when i detect "i am on the slope", which solves the sliding issues partially, but these will create ugly collision bugs :-(
 
My goal is to control when i slide and when i dont - which is not physically correct, but makes it much more fun.
 
Also i dont have any physical friction at all - i manually do friction for (on ground, in air, changing direction, standing etc.) like this:

// We are on ground when the collision systems says so
boolean grounded = state.player.collisionState.contains(CollisionState.Ground);

// Apply ground friction
float friction = 1f;
if (grounded) {
	if (Math.abs(state.player.acc.x) > 0) {
		if (state.player.acc.x < 0 && state.player.vel.x > 0) {
			friction = state.player.groundAccelTurnFriction;
		} else {
			friction = state.player.groundAccelFriction;
		}
	} else {
		friction = state.player.groundDefaultFriction;
	}
} else {
	if (Math.abs(state.player.acc.x) > 0) {
		if (state.player.acc.x < 0 && state.player.vel.x > 0) {
			friction = state.player.airAccelTurnFriction;
		} else {
			friction = state.player.airAccelFriction;
		}
	} else {
		friction = state.player.airDefaultFriction;
	}
}
state.player.vel.x += state.player.vel.x * -1f * friction * GameTime.dt;

Share this post


Link to post
Share on other sites
Advertisement
If you know your contact normal, you could use the perpendicular as the friction direction and turn your computation from 1D to 2D.
Further you need to add static friction, which is able to stop your character if slope and relative velocity are small enough.

Edit: the above might be more physical than you want / necessary, but i assume the sliding is maybe not caused by missing friction.
E.g. character penetrates ground due to vertical gravity, but collision is resolved along the sloped contact normal, so it slides a bit down and to the side.
Is this the case, and you can't prevent it from happening even by setting state.player.vel.x to zero?

Maybe you should post collision resolving code too. Edited by JoeJ

Share this post


Link to post
Share on other sites

If you know your contact normal, you could use the perpendicular as the friction direction and turn your computation from 1D to 2D.
Further you need to add static friction, which is able to stop your character if slope and relative velocity are small enough.

Edit: the above might be more physical than you want / necessary, but i assume the sliding is maybe not caused by missing friction.
E.g. character penetrates ground due to vertical gravity, but collision is resolved along the sloped contact normal, so it slides a bit down and to the side.
Is this the case, and you can't prevent it from happening even by setting state.player.vel.x to zero?

Maybe you should post collision resolving code too.

 

Hmm, maybe adding friction as a tangent impulse may solve that problem - but the friction must be computed on the fly to account for steep angles.

I will try using mixed friction method and report back - when i got time ...

Share this post


Link to post
Share on other sites

E.g. character penetrates ground due to vertical gravity, but collision is resolved along the sloped contact normal, so it slides a bit down and to the side.


If this is happening, it might be easier to try this at resolving collision:
vec2 resolve = resolvedPosition - penetratingPosition;
if (fabs(resolve.x) / fabs(resolve.y) < 0.55) // angle is less 45 (that,s a large threshold for this method, but you get the idea)
{
resolve.x = 0; // force resolving only vertical
resolvedPosition = penetratingPosition + resolve; // some penetration is left but will converge
}
A bit hacky but it may suit your needs.
You could also use higher left friction and lower right friction if the slope goes down right side for more realism to keep it simply 1D. Edited by JoeJ

Share this post


Link to post
Share on other sites

Okay i added basic friction support using material mixing, but now its getting much more complicated:

 

- I need to add multiple shapes/collider support to fix wall glue bug (friction on the side is not a good idea - except i want honeylike behavior)

- Need to add circle shape/collider support for player feet shape to get more friction when walking along a slope

- Tuning material frictions is very hard (Are there a good guide for this - especially what friction coefficient should have the player feet - one?)

 

Maybe that will solve my problems by walking along slopes - without being pushed back by edge contacts or pushed down by gravity - who knows...

 

The only thing which i dont know: Will i need static friction as well??

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement