3
\$\begingroup\$

I have different game objects with rigid bodies, each having its own mass and drag. However, when these objects fall, they appear to fall at equal speeds. This raises the question of why they do not reach the ground at different times. You can watch a video explanation of this phenomenon here.

\$\endgroup\$
5
  • \$\begingroup\$ It looks to me like you haven't used a wide enough range of drag values to see noticeable differences over that fall distance. Remember that mass does not change fall speed in this model, so you might be expecting a larger effect than the math would predict. \$\endgroup\$
    – DMGregory
    Jul 9, 2023 at 13:21
  • \$\begingroup\$ You mean that the object mass will not make signficiant distance, only i have to play with drag ? Then, it will be hard to build a simulator around this concept. Do i need to increase the distance ? \$\endgroup\$ Jul 9, 2023 at 13:25
  • \$\begingroup\$ Keep in mind that game engines are only so close to real physics. They have physics to make enjoyable game but a realistic simulation might have different needs \$\endgroup\$
    – Zibelas
    Jul 9, 2023 at 15:16
  • 5
    \$\begingroup\$ Object mass will not change acceleration due to gravity (Galileo showed that), and linear drag is applied as a geometric reduction in speed (speed multiplied by some ratio < 1 each tick), so mass does not have any influence on the time it takes to fall. You can simulate mass-aware air resistance in your own code if you need it. \$\endgroup\$
    – DMGregory
    Jul 9, 2023 at 15:50
  • \$\begingroup\$ Bowling ball vs feather in a vacuum \$\endgroup\$ Jul 10, 2023 at 17:37

1 Answer 1

9
\$\begingroup\$

Check out the implementation of linearDamping in PhysX here (what Unity calls Linear Drag in the Rigidbody built on top of PhysX). It's equivalent to:

velocity = velocity * (1f - linearDamping * Time.deltaTime);

This is not a physically accurate model of air resistance - it's just a cheap calculation to let excess velocity decay away, damping down jitters in the physics system.

You'll notice that it doesn't include mass. Neither does acceleration due to gravity (a heavy object feels a greater force of gravitational attraction, but also requires more force to accelerate, and these two effects exactly cancel each other out).

So that means in your example, the only difference between these three objects is that one has a damping of 0.3 and the others have a damping of 0.1.

As I show in this spreadsheet sim, that's only enough to delay the impact of the first object by 0.04 seconds over a 5 meter drop - that's only a little more than a single frame at 30 fps - so it's not surprising that there's no perceptible difference here.

Spreadsheet simulation

Real air resistance is a force proportional to cross sectional area and speed (or proportional to the square of speed at high speeds), and heavy objects accelerate less for the same force, so that's where the intuitive idea that the heavy object should fall faster comes from. But this is much more expensive to calculate, even approximately, and different games will have different needs in terms of speed/realism trade-offs, or different types of fluid interactions they need to model. So for efficiency, physics engines don't make any attempt to model this messy phenomenon by default — they just give you a cheap way to make things slow down and stop jittering.

But that doesn't stop you from writing your own air resistance calculation - to whatever degree of accuracy is appropriate for your game's needs - and injecting that into the physics tick using FixedUpdate, something like this:

[RequireComponent(typeof(Rigidbody))]
public class AirDrag : MonoBehaviour {

    public float dragCoefficient;

    // You could calculate this automatically from the colliders / bounds,
    // or even recompute it for each direction of travel.
    // Tumbling bodies are left as an exercise for the reader. 😜
    public float crossSectionalArea;

    [SerializeField, HideInInspector]
    Rigidbody _body;

    void OnValidate() {
        if (_body == null) TryGetComponent(out _body);
    }

    void FixedUpdate() {
        Vector3 vel = _body.velocity;
        float speed = vel.magnitude;

        // Assume high speed flow, drag proportional to square of speed.
        Vector3 drag = -vel * speed * dragCoefficient * crossSectionalArea;

        // How much force would be required to stop the object entirely?
        float limit = _body.mass * speed / Time.deltaTime;

        // Ensure we never accelerate more than that (no reversing direction).
        drag = Vector3.ClampMagnitude(drag, limit);

        // Apply the clamped drag.
        _body.AddForce(drag);
    }
}
\$\endgroup\$
4
  • 1
    \$\begingroup\$ "no perceptible difference" - It seems very perceptible to me that the right one lands first, then the middle, then the left. The "height" values for the the middle- and right-ones are always the same, for the reasons explained above. The reason the right lands first is that its starting position was shifted down. Here's a screenshot just as the ball lands. \$\endgroup\$ Jul 10, 2023 at 6:23
  • \$\begingroup\$ in order to realistically simulate physics, we have to only manage air drag. Will this be a good simulator? Or it will clearly tech to gravity concept to student? \$\endgroup\$ Jul 16, 2023 at 5:26
  • \$\begingroup\$ @BlueRaja-DannyPflughoeft The difference is not significant. \$\endgroup\$ Jul 16, 2023 at 5:40
  • \$\begingroup\$ "Good" is a subjective perception. You can test it out and evaluate how well it meets your leaning goals. \$\endgroup\$
    – DMGregory
    Jul 16, 2023 at 11:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .