3D Rigidbody sliding issue: 3D Rigidbodies slowly slide down slopes even with maximum friction settings, moving at a speed of 0.001f. Please fix this issue that exists across all Unity versions.
A rigidbody won’t slide down a slope if there’s enough friction. But if the rigidbody is a sphere then it will always roll down a slope regardless of how much friction there is. This is also what happens in reality. Friction doesn’t prevent rolling, it only prevents sliding.
When adding this line in FixedUpdate, 3D Rigidbodies will slide down, while 2D Rigidbodies won’t slide (with friction set above 10). When implementing third-person character movement with 3D Rigidbodies, the character will slowly slide down when standing still on slopes.
//This line:
private void FixedUpdate()
{
rb.velocity = rb.velocity;
}
Heya,
Can you expand a bit more there on this?
Is the velocity at that point very close to 0 in your use-case?
Cheers,
AlexRvn.
You probably meant:
rb.velocity = -rb.velocity;
But yes, if the slope is very steep then that may fail. Although that’s not really the physics friction and it’s just your script trying to override any slipping.
You can add a physics material to your character and increase the material’s friction and set the ‘Friction Combine’ to Maximum to prevent the slope’s own friction settings from having any influence.
Or some developers choose to just disable or cancel out gravity when their character is on a slope.
This is done so that when a third-person character is stationary, they can still interact physically with any object. For example: if the slope is destroyed, the character can fall; if the slope continues to tilt, the character can react physically; if an object hits the character, they can respond to being pushed. You can try this effect, but 3D Rigidbodies will slowly slide down, while 2D Rigidbodies won’t exhibit this behavior (when friction is greater than or equal to 10).
It’s not rb.velocity = -rb.velocity, but rb.velocity = rb.velocity.
This is done so that when a third-person character is stationary, they can still interact physically with any object. For example: if the slope is destroyed, the character can fall; if the slope continues to tilt, the character can react physically; if an object hits the character, they can respond to being pushed. You can try this effect, but 3D Rigidbodies will slowly slide down, while 2D Rigidbodies won’t exhibit this behavior (when friction is greater than or equal to 10).
HD.rar (17.8 MB)
I uploaded an MP4 video compressed in RAR format. Once you extract it, you can see the detailed video content showing the character slowly sliding down along the Y-axis when on a slope.
//This line:
private void FixedUpdate()
{
rb.velocity = rb.velocity;
}
Oh I see it!. You’re using rb.velocity=rb.velocity to keep the rigidbody awake and as a result it’s preventing friction from bringing the rigidbody to a complete stop.
The slipping velocity was very low and so I doubt anybody will notice it.
Hmm the way to solve this is a bit more complex than just doing rb.velocity = rb.velocity (I’ll check if there’s a way we could sanitize this input).
But I’d recommend doing the following:
- when you stop add a heuristic to put the rigidbody to sleep (it is still affected by forces/collisions etc)
- only set velocity when input is being provided / when velocity is larger than a specific threshold you define (allows for fine control over when the character is awakened vs not)
[I’m aware that w/o having the complete picture of how you input the velocity here either by velocity change or .AddForce/Torque the approach presented above might or might not work out]
Will be back with an answer on sanitizing the inputs from our side, I’m curious if we can do something here.
Cheers,
AlexRvn.