RigidBody.AddForce causes capsule collider to trip on a surface with friction

When I add force to an object with a capsule collider and friction, it tips over. I’ve tried using AddForceAtPosition at the bottom of the object, but I find this really hard to balance and the object tends to rotate in the opposite direction.

Does anyone know if there’s a way to apply force evenly over the entire object instead of the center of mass? Thanks!

You can set the Freeze Rotation flags in the Rigidbody Constraints section.
172791-rbnorotation.png

Okay so I’ve tried a lot of things, I’ll list here what I’ve tried, why I didn’t like those solutions, and finally the solution that worked for me.


Firstly, I tried applying force just at the base of my object, this didn’t work and caused the object to tip in the opposite direction do to the torque applied.


Secondly, I tried writing a ‘keep upright’ script to apply torque against the rotation of the object. This didn’t quite work and became very difficult to balance. I noticed a lot of oscillation and unexpected behavior when the object would get in strange positions. Balancing this with the friction seemed to be a nightmare and would have to be redone for every object using this script of different mass. It seemed like a good idea but I wouldn’t recommend this to counteract frictional tipping.


Thirdly I tried applying force at 3 different points along the object, one at the center of mass, one at the base of the object, and one at the top of the object. Surprisingly, this didn’t work at all and led to a lot of unexpected behavior. You may be able to get this to work by calculating the force required to overcome friction on the bottom point, but I think this would be a lot more work and still result in unexpected behavior.


The Solution: I ended up removing friction completely on my object and writing a movement dampening function that runs only when the object is on the ground. This basically allows friction to be applied at the center of mass instead of at the contact point. Here is the script I wrote for that:

//Movement Dampening:
        Vector3 forceVector;
        if (physics.velocity.y < 0) {
            forceVector = new Vector3(-physics.velocity.x, Physics.gravity.magnitude/movementDampeningFactor, -physics.velocity.z);
        }
        else {
            forceVector = new Vector3(-physics.velocity.x, 0, -physics.velocity.z);
        }
        physics.AddForce(forceVector * movementDampeningFactor, ForceMode.Acceleration);