I am building a 3D rigidbody physics simulation with modular attachable components. I have a single rigidbody on a parent object, and as I attach or remove modules I add to or subtract from the parent rigidbody mass. I also have a collider associated with each component, and I would like to use the rigidbody physics to automatically calculate the inertia tensor and center of mass of the full system of colliders.

The Unity rigidbody component seems to assume uniform mass density among children colliders. Is there a way for me to adjust that assumption that is not based on collider size? I would like to be able to assign a small, attachable module a large mass without making its collider larger than its physical size.

This piece of code should do the trick:

Warning: This is only accurate for cube Sized Modules as children. If you want to use other things use a different approach for inertia of simple geometry forms. ->wikipedia or something. (for cubes its mass*sidelength/6)

```
private void recalculateMassAndInertia()
{
Vector3 newCenterOfMass = Vector3.zero;
Vector3 newInertiaVector = Vector3.zero;
Vector3 distance = Vector3.zero;
YourModuleScript m;
float sumOfMass = 0;
foreach (Transform t in allConnectedModules) {
if (t.gameObject.GetActive ()) {
m = t.GetComponent<YourModuleScript> ();
newCenterOfMass += (t.localPosition * m.mass);
sumOfMass += m.mass;
}
}
newCenterOfMass = newCenterOfMass /sumOfMass;
Debug.Log (newCenterOfMass);
foreach (Transform t in allConnectedModules) {
if (t.gameObject.GetActive ()) {
m = t.GetComponent<YourModuleScript> ();
distance = new Vector3 (Mathf.Pow (t.localPosition.y - newCenterOfMass.y, 2.0f) + Mathf.Pow (t.localPosition.z - newCenterOfMass.z, 2.0f), Mathf.Pow (t.localPosition.x - newCenterOfMass.x, 2.0f) + Mathf.Pow (t.localPosition.z - newCenterOfMass.z, 2.0f), Mathf.Pow (t.localPosition.x - newCenterOfMass.x, 2.0f) + Mathf.Pow (t.localPosition.y - newCenterOfMass.y, 2.0f));
newInertiaVector += ((Vector3.one * m.mass *m.sidelength/ 6.0f) + m.mass* distance);
// if your parent object is in the list: detect it and use this line for this module:
//newInertiaVector += (Vector3.one * m.mass *m.sidelength/ 6.0f);
}
}
GetComponent<Rigidbody> ().centerOfMass = newCenterOfMass;
GetComponent<Rigidbody> ().inertiaTensor = newInertiaVector;
GetComponent<Rigidbody> ().mass = sumOfMass;
Debug.Log (sumOfMass);
}
```

You have to add your own script to keep track of the modules mass. This should go wherever you find “yourModuleScript” and it should have a public float property named “mass”. Also this script assumes that you have all your modules set in a List “allConnectedModules”.

Note:

im not sure in wich order to set the mass/inertia/center of mass to prevent unity from automatically recalculating on its own.

Please let me know if you have any idea about this.