Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We’re making changes to the Unity Runtime Fee pricing policy that we announced on September 12th. Access our latest thread for more information!
    Dismiss Notice
  3. Dismiss Notice

Understanding Rudimentary Unity Physics

Discussion in 'Physics' started by Nigey, Apr 14, 2016.

  1. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    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?
     
  2. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Unity uses nVidia's physx for 3D physics and Box2d for 2d physics.
     
  3. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    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?
     
  4. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    No, they are both well documented.

    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.
     
    Nigey likes this.
  5. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,414
    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:

    http://docs.nvidia.com/gameworks/co...physx/guide/Manual/RigidDynamics.html#damping
     
    Nigey and eses like this.
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,218
    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:

    linearVelocity *= 1.0f / (1.0f + timeSlice * LinearDrag)
    angularVelocty *= 1.0f / (1.0f + timeSlice * AngularDrag)


    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.
     
    seandanger, Black_Demon and Nigey like this.
  7. steinbitglis

    steinbitglis

    Joined:
    Sep 22, 2011
    Posts:
    247
    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.
     
  8. steinbitglis

    steinbitglis

    Joined:
    Sep 22, 2011
    Posts:
    247
    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.
     
  9. tomweiland

    tomweiland

    Joined:
    Dec 15, 2017
    Posts:
    19
    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.

    Code (CSharp):
    1. private void FixedUpdate()
    2. {
    3.     body.velocity *= Mathf.Max(1f - drag * Time.fixedDeltaTime, 0f);
    4. }
    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 AddForce and to the velocity every physics step (as shown above). For example:

    Code (CSharp):
    1. float dragMultiplier = Mathf.Max(1f - drag * Time.fixedDeltaTime, 0f);
    2. Vector3 initialForce = Vector3.up * 50;
    3. body.AddForce(initialForce * dragMultiplier, ForceMode.VelocityChange);
    4. compareTo.AddForce(initialForce, ForceMode.VelocityChange);
    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 :)
     
    Edy likes this.
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,218
    As I stated above, the one I mentioned is Box2D only and it's the one it still uses today so isn't "outdated". :) Nothing to do with PhysX though.
     
    tomweiland likes this.
  11. tomweiland

    tomweiland

    Joined:
    Dec 15, 2017
    Posts:
    19
    Ah right, that makes sense. My bad for missing the part about it being for 2D :oops:
     
    MelvMay likes this.
  12. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,218
    it's okay, sometimes both are discussed as the same thing and there's a lot of cross-over but obviously not everything.

    I was really only replying to ensure future readers don't take that as fact because many do. :)
     
    tomweiland likes this.