I have run into similar problems and after days of testing I think I know the answer.
I was trying to stack rigidbodies and sometimes they “sink” into each other.
The “sinking” can be caused by many reasons. The root cause is the way the physics engine works. I have theories but without examining Unity/PhysX source code they will remain theories.
Usually the problem arises from the constrains of the Rigidbodies.
(1) Always, always have objects scaled to 1,1,1. Different scales may not seem to affect the object right away, but they will come to haunt you. See here for why: Rigidbody.centerOfMass
(2) Are any of your Rigidbodies significantly heavier than others?
An object with 100 mass will sink very deep into an object with 0.1 mass.
(3) In the Inspector, under Rigidbody, do you have “Freeze Position” checked for any of your axes? Check all components for this.
If so, bodies will tend to “sink” in the frozen axis.
This can be partially fixed by increasing the mass of the object that is sunk into. If you don’t want to do that then you could try the solution under (4), though I don’t think it should work.
(4) Do you have “Freeze Rotation” checked for any of your axes?
If so, bodies will sink when trying to apply torque on the frozen axis. The sinking is increased the further you are from the local frozen axis and seems to increase with more objects applied, even if the objects aren’t touching.
This is caused by Wikipedia Moment of inertia and the way the physics engine works with it.
You could set this manually via this and this if you know what you’re doing (college physics).
Or you could do what I’m currently doing: Add a Layer(google if you don’t know how), name it something like “Ignore Collision” In Edit-> Project Settings-> Physics uncheck all the boxes in the Layer Collision Matrix for the Layer Ignore Collision. Now add a child object with only a collider to your spaceship, set the collider layer to Ignore Collision. Make the collider long in the direction perpendicular to the Frozen Axis. For example if Z rotation is Frozen, make the collider long in X or Y. If all rotation is frozen then just make the collider long in all axes. This might also partially solve problems mentioned in (3).
Edit: I just tried setting the Rigidbody.inertiaTensor manually and it seems to work as well.
Example: If objects sink with Z rotation frozen, add a script to the object with the rigidbody
void Start () {
rigidbody.inertiaTensor = rigidbody.inertiaTensor + new Vector3(0, 0, rigidbody.inertiaTensor.z * 100);
}
This script doesn’t affect the X and Y axes and sets the inertiaTensor for Z to be 101 times the original value.
If you want less sinking increase the mass or increase the 100.
Since Z rotation is frozen anyway, this should not have too many side effects other than less sinking.
I like this solution better as it does not involve messing with layers and huge ghost colliders that could effect performance(not confirmed). The downside is you may forget and if you unlock the Z rotation later on, don’t forget to change the inertiaTensor back or else your object will seem really heavy when rotating about Z.
Why do things sink? I think its because the freeze position/rotation option is bugged. Objects pushing on frozen objects don’t realize that they are frozen, and keep pushing at the same “force” as if they weren’t frozen. This force/sinking is somewhat inverse to the mass and moment of inertia stuff so increasing these decrease the sinking problem.