Spinning a sphere in place causes unwanted velocity.


I’m playing around with moving a sphere using rigidbody physics. Right now I have the sphere and floor set up with physics materials and am tweaking them to get a good balance of traction as well as sliding/spinning depending on how fast the sphere is moving. The sphere is being controlled with the AddTorque function, and I’m having some issues when it loses traction/spins/slides on the floor. So I’m moving forwards and backwards and when I switch from one to the other the floor’s friction isn’t high enough so the sphere spins which i what I want, however there’s velocity/force being added to the left/right for some reason. Here’s a video showing what I’m experiencing.

Can someone explain what it is that is happening? I’m only applying torque to move forward and backward but when it slides it moves left and right. I’m having trouble determining why it’s doing this.

I think your sphere is moving sideways because there is a lot more going on than it appears at first glance. From a physics standpoint, there are a lot of non-linearity’s associated with friction, especially when an object has enough torque to overcome static friction and move into dynamic friction, which is what happens when your sphere begins to spin when changing directions. Without getting into the nitty-gritty, a ton of crazy things can happen in this situation.

I’m not familiar with the inner workings of PhysX or how Unity uses it, so anything from here on is speculation. Your sphere isn’t perfect, its made up of about 1500 vertices, so as your ball rolls you will have a different amount of vertices contacting the ground at any given time, and the forces applied to your sphere by the ground are ever so slightly different. Eventually, the small amount of instability adds up, along with what I mentioned in the above paragraph, and the final result is your sphere sways to one side or the other.

So my guess is that the physics engine is much more accurate than most people realize, someone with a better understanding of PhysX and Unity could tell you for sure.

A quick solution would be to freeze your rigid body’s position in the swaying direction. Check if your input direction is the same as your rigid body’s. If they’re different, constrain your rigid body, otherwise, don’t constrain.

	private Rigidbody rBody;
	private RigidbodyConstraints rc;

	void Update () {

		Vector3 travelDirection = rBody.velocity;
		Vector3 inputDirection = Vector3.back;

		if (travelDirection.z > 0 && inputDirection.z < 0) {
			rc = RigidbodyConstraints.FreezePositionX;
			rBody.constraints = rc;
		} else {
			rc = RigidbodyConstraints.None;
			rBody.constraints = rc;