Unity’s physics engine works great, but a lot of the numbers it uses seem to be drawn randomly from a hat and have no real world value (from what I can see). Does anyone know the real world equivalents?
Like for example:
Mass - I’m guessing this is in meters (as 1 Unity unit = 1 meter)?
Drag - I assume this is ignoring form, induced, wave, interference drags, and skin friction. It’s just a number that is picked out of the air (hah), to represent drag force. However the name is too abstract. Does this actually represent drag force, or the drag coefficient (drag coefficient is a combination of skin friction and form drag, and drag force is the overall force upon the object, subject to current speed, which increases the pressure/force an object is pushing against)?
Angular Drag - Ignoring again all forms of drag equations, and is just an abstract number to represent the angular drag on an object.
Is there some way to find out more details on what equations are actually happening? Asides of course using your own custom physics engine?
So you suggest I download the Nvidia PhysX source and route through that? Do you know whether Unity makes any custom changes to it? Or is this simply no one but someone with Unity Engine’s source code will know?
I have no idea what custom changes Unity make but I’d assume the docs for the two implementations would be a good place to start.
For the things you’ve queried I can’t imagine there’d be significant customisation over the default implementation. I could be very wrong, but that’s my guess.
Unity physics (PhysX) use the international system of units (SI)
Mass: kilograms
Drag: a damping rate causing a force that opposes the velocity of the rigidbody. If drag is zero then you have pure newtonian cinematics: the object will conserve its momentum (velocity) unless external forces are applied (gravity included). if drag is nonzero then the rigidbody will come to stop even when no other force is acting on it.
Angular Drag: same as drag, but affecting the angular momentum (rotation rate). If angular drag is nonzero, then the object will eventually stop rotating even if no force/torque is acting on it.
The documentation for PhysX is a good place to learn more on Unity physic internals. The drag properties (named damping in PhysX) are described here:
2D physic uses Box2D which uses MKS or Meters-Kilograms-Seconds. For the most part, units are in SI Units.
Distance is in m (Meters)
Mass is in Kg (Kilograms) - Note you thought it was Meters which is a distance.
Time is in s (Seconds)
Drag (Linear Drag) & Angular Drag are cooefficients that damp the linear/angular velocity over time. They don’t have specific units but are applied per fixed-update to a body using the following pseudo-code like so:
For completeness, the body linear velocity is updated like so: linearVelocity += timeSlice * (GravityScale * WorldGravity + (1.0f / Mass) * BodyAppliedForce)
Here’s how the angular velocity is updated angularVelocity += timeSlice * (1.0f / Inertia) * BodyAppliedTorque
You can find all the above in the Box2D source code here (around line #203).
Box2D is designed to simulate physics enough for a game simulation. It’s not designed to perform accurate simulations of physical reality hence the approximations.
I’ve tried for a whole day to implement two falling cubes, where I do manual drag in a script, and the reference rigidbody2d in the other, but I can’t seem to get them to fall synchronously. Is this a trivial task that I’m just getting wrong, or is there something complicated going on?
If anyone else is able to do this, I would love to analyze your working example.
By the way, what I’ve been doing is to let two identical capsules fall synchronously into a BuoyancyEffector2D with a polygon collider. I don’t know if that’s relevant.
I came across this thread while trying to solve the same problem, and I believe I’ve figured out why none of the formulas mentioned in various forum and Unity Answers posts seem to work.
I think the formula mentioned in this thread (linearVelocity *= 1.0f / (1.0f + timeSlice * LinearDrag)) may be outdated, as a more recent answer claims that Unity calculates drag like this instead: velocity = velocity * (1 - deltaTime * drag);
That also matches up with what I found in the PhysX source code, and yet when I tried this with 2 cubes (each with a rigidbody), one using the built in drag and the other using the code below, they fell to the ground at different speeds.
This is simply due to the order in which things happen. When PhysX applies drag internally, it does so after applying gravity (and I think after integrating all accumulated forces from AddForce calls since the last physics step). Meanwhile, when we modify the velocity directly in FixedUpdate, gravity and any forces that were applied since the last physics step have not yet been integrated into said velocity. This essentially results in forces having a whole physics step to move the object before they’re actually affected by drag.
To test this, I disabled gravity and applied a 50m/s VelocityChange force upwards to both objects. Regardless of what I set the drag to, the object using the custom drag always ends up 1 unit higher than the one using the built in drag. This is because the default fixed timestep is 0.02, and the object with the custom drag gets one “free” physics step with no drag applied. 50m/s * 0.02 = 1, which is how far the object travels during that first step, and that’s where it gets the extra 1 unit compared to the object using the built in drag.
The only way I could think of solving this problem was by applying the drag multiplier to forces as you add them via AddForceand to the velocity every physics step (as shown above). For example:
body is the object using the custom drag and compareTo is the object using built in drag. Both will come to rest at the same y position, provided they started at the same height and didn’t bump into anything.
As far as I can tell this works for all force modes