Class VariableCenterOfMass
Dynamic center of mass and inertia calculation system that updates Rigidbody properties based on attached mass affectors like fuel tanks, cargo loads, and passengers.
Namespace: NWH.Common.CoM
Assembly: NWH.Common.dll
Syntax
[DisallowMultipleComponent]
[DefaultExecutionOrder(-1000)]
[RequireComponent(typeof(Rigidbody))]
public class VariableCenterOfMass : MonoBehaviour
Remarks
VariableCenterOfMass enables realistic vehicle physics behavior by automatically adjusting center of mass and inertia tensor as vehicle loading changes. This affects handling characteristics, stability, and acceleration response without requiring complex rigidbody hierarchies.
The system calculates total mass, weighted center of mass position, and inertia contributions from all IMassAffector components. Changes in fuel level, cargo loading, or passenger weight immediately affect vehicle dynamics, creating realistic weight distribution effects.
Critical for vehicle realism: Front-heavy vehicles understeer more, rear-heavy vehicles may oversteer, and high center of mass increases rollover tendency. The system updates these characteristics dynamically based on actual mass distribution.
Fields
| Edit this page View Sourceaffectors
Objects attached or part of the vehicle affecting its center of mass and inertia.
Declaration
[NonSerialized]
public IMassAffector[] affectors
Field Value
| Type | Description |
|---|---|
| IMassAffector[] |
baseMass
Base mass of the object, without IMassAffectors.
Declaration
[Tooltip("Base mass of the object, without IMassAffectors.")]
public float baseMass
Field Value
| Type | Description |
|---|---|
| float |
centerOfMass
Center of mass of the object. Auto calculated. To adjust center of mass use centerOfMassOffset.
Declaration
[Tooltip("Center of mass of the rigidbody. Needs to be readjusted when new colliders are added.")]
public Vector3 centerOfMass
Field Value
| Type | Description |
|---|---|
| Vector3 |
combinedCenterOfMass
Combined center of mass, including the Rigidbody and any IMassAffectors.
Declaration
public Vector3 combinedCenterOfMass
Field Value
| Type | Description |
|---|---|
| Vector3 |
combinedInertiaTensor
Total inertia tensor. Includes Rigidbody and IMassAffectors.
Declaration
public Vector3 combinedInertiaTensor
Field Value
| Type | Description |
|---|---|
| Vector3 |
combinedMass
Total mass of the object with masses of IMassAffectors counted in.
Declaration
[Tooltip("Total mass of the object with masses of IMassAffectors counted in.")]
public float combinedMass
Field Value
| Type | Description |
|---|---|
| float |
dimensions
Object dimensions in [m]. X - width, Y - height, Z - length. It is important to set the correct dimensions or otherwise inertia might be calculated incorrectly.
Declaration
[Tooltip("Object dimensions in [m]. X - width, Y - height, Z - length.\r\nIt is important to set the correct dimensions or otherwise inertia might be calculated incorrectly.")]
public Vector3 dimensions
Field Value
| Type | Description |
|---|---|
| Vector3 |
inertiaTensor
Vector by which the inertia tensor of the rigidbody will be scaled on Start(). Due to the uniform density of the rigidbodies, versus the very non-uniform density of a vehicle, inertia can feel off. Use this to adjust inertia tensor values.
Declaration
[Tooltip(" Vector by which the inertia tensor of the rigidbody will be scaled on Start().\r\n Due to the unform density of the rigidbodies, versus the very non-uniform density of a vehicle, inertia can feel\r\n off.\r\n Use this to adjust inertia tensor values.")]
public Vector3 inertiaTensor
Field Value
| Type | Description |
|---|---|
| Vector3 |
isDirty
When true, properties will be recalculated in the next FixedUpdate. Call MarkDirty() when mass affectors change to trigger update.
Declaration
[Tooltip("When true, properties will be recalculated in the next FixedUpdate. Automatically managed.")]
public bool isDirty
Field Value
| Type | Description |
|---|---|
| bool |
useDefaultCenterOfMass
When enabled the Unity-calculated center of mass will be used.
Declaration
[Tooltip("When enabled the Unity-calculated center of mass will be used.")]
public bool useDefaultCenterOfMass
Field Value
| Type | Description |
|---|---|
| bool |
useDefaultInertia
When true inertia settings will be ignored and default Rigidbody inertia tensor will be used.
Declaration
[Tooltip("When true inertia settings will be ignored and default Rigidbody inertia tensor will be used.")]
public bool useDefaultInertia
Field Value
| Type | Description |
|---|---|
| bool |
useDefaultMass
Should the default Rigidbody mass be used?
Declaration
public bool useDefaultMass
Field Value
| Type | Description |
|---|---|
| bool |
useMassAffectors
If true, the script will search for any IMassAffectors attached as a child (recursively) of this script and use them when calculating mass, center of mass and inertia tensor.
Declaration
public bool useMassAffectors
Field Value
| Type | Description |
|---|---|
| bool |
Methods
| Edit this page View SourceCalculateInertia(Vector3, float)
Calculates inertia tensor for a cuboid with given dimensions and mass. Uses parallel axis theorem for rectangular prism approximation.
Declaration
public static Vector3 CalculateInertia(Vector3 dimensions, float mass)
Parameters
| Type | Name | Description |
|---|---|---|
| Vector3 | dimensions | Object dimensions in meters (width, height, length) |
| float | mass | Total mass in kilograms |
Returns
| Type | Description |
|---|---|
| Vector3 | Inertia tensor components (Ix, Iy, Iz) in kg⋅m² |
CalculateInertiaTensorOffset(Vector3)
Calculates the inertia tensor of the Rigidbody and attached mass affectors.
Declaration
public Vector3 CalculateInertiaTensorOffset(Vector3 dimensions)
Parameters
| Type | Name | Description |
|---|---|---|
| Vector3 | dimensions |
Returns
| Type | Description |
|---|---|
| Vector3 |
CalculateMass()
Calculates the mass of the Rigidbody and attached mass affectors.
Declaration
public float CalculateMass()
Returns
| Type | Description |
|---|---|
| float |
CalculateRelativeCenterOfMassOffset()
Calculates the center of mass of the Rigidbody and attached mass affectors.
Declaration
public Vector3 CalculateRelativeCenterOfMassOffset()
Returns
| Type | Description |
|---|---|
| Vector3 |
GetMassAffectors()
Updates list of IMassAffectors attached to this object. Call after IMassAffector has been added or removed from the object.
Declaration
public IMassAffector[] GetMassAffectors()
Returns
| Type | Description |
|---|---|
| IMassAffector[] |
GetWorldCenterOfMass()
Gets the combined center of mass position in world space coordinates.
Declaration
public Vector3 GetWorldCenterOfMass()
Returns
| Type | Description |
|---|---|
| Vector3 | World space position of the center of mass |
MarkDirty()
Mark properties as needing recalculation. Call this when mass affectors change (fuel consumption, cargo loading, etc.).
Declaration
public void MarkDirty()
UpdateAllProperties()
Recalculates all Rigidbody properties (mass, center of mass, and inertia) based on current settings and affectors. Called automatically when isDirty flag is set.
Declaration
public void UpdateAllProperties()
UpdateCoM()
Calculates and applies the CoM to the Rigidbody.
Declaration
public void UpdateCoM()
UpdateInertia(bool)
Calculates and applies the inertia tensor to the Rigidbody.
Declaration
public void UpdateInertia(bool applyUnchanged = false)
Parameters
| Type | Name | Description |
|---|---|---|
| bool | applyUnchanged |
UpdateMass()
Calculates and applies the total mass to the Rigidbody. Includes mass from affectors if useMassAffectors is enabled.
Declaration
public void UpdateMass()