I’ve created a pile of spheres (with some walls around them so they can’t roll away) using regular SphereColliders and Rigidbodies, and then dragged them into a subscene to author them into entities & components. When I hit play, this pile of spheres behaves pretty weirdly. Rather than the spheres resting in a pile nice and still, many of the spheres seem to spin in place. They wont move linearly, but they’ll rotate at a constant (small) speed.
I don’t have any code interacting with these entities (it’s a completely fresh scene in a new project). This doesn’t happen with regular PhysX gameobjects. what gives? Is there a way to prevent this behaviour, or is this just the trade-off of statelessness?
Things I’ve tried
Increasing solver iterations - This does reduce the effect, but it’s still noticeable unless I increase the number to something totally absurd
Messing with all the other properties of PhysicsStep, including all the stabilization heuristics outlined here
EnableFrictionVelocities
EnableSolverStabilization
VelocityClippingFactor - this one specifically
InertiaScalingFactor
Increasing angular drag
Increasing friction, both by changing the PhysicsCollider’s friction programmatically, and by applying a physicmaterial with static and/or dynamic friction to the authoring GO
Trying each collision detection setting
Change to Havok - this does fix it (the balls will still spin at first, but they’ll settle after maybe 20 seconds and stop spinning), but Havok is a no-go for us unfortunately
This is easily reproducible in a fresh project, Pic below - just imagine some of these balls spinning in place!
Unity Physics is stateless, that is, it doesn’t carry information from one simulation frame to the other. It just resolves whatever situation it encounters on each frame. PhysX and Havok include algorithms that are aware of the situation along multiple simulation frames and apply stabilization strategies. That may explain why Unity Physics exhibits that behavior, while the others don’t.
Yes, I’m familiar with stateless vs stateful, it still feels like this behaviour is erroneous, even given the statelessness of UnityPhysics. I would expect angular velocity to be dampened as a function of angular drag and friction with the other bodies the spheres are colliding with, it seems like there’s something driving this rotation (as in, something about the state in the current frame is forcing the ball to spin), and whatever that is at equilibrium with whatever damping is happening… it’s that driving force that I’m trying to get to the bottom of
This sort of confinement case is a challenging scenario for typical iterative rigid body dynamics solvers used in games.
It’s possible that the reason that the spinning stops in PhysX (built-in physics) and Havok is their sleeping functionality. See “Sleep Threshold” for built-in physics here.
These engines deactivate rigid bodies when the velocity falls below a certain velocity threshold.
In Unity Physics we don’t implement this sort of sleeping since this requires additional previous frame state information and Unity Physics is stateless by design.
You could though modify the source code to stop the spinning by simply setting rigid body velocities to zero before calculation of the next frame’s positions and rotations. This would very effectively stabilize this simulation.
Let me know if this is something that you are interested in and I can provide more details.