How to find the force being applied to a rigidbody

I’m sure there’s a simple way to do this but I’m kinda new and I couldn’t find anything in the docs. What I really want is a variable, a vector 3, that shows the total amount of force (not velocity) being applied to a rigidbody object by anything, be it rigidbody.addforce, gravity, or another object pushing it. This information will be extremely helpful to me so thank you for helping.

1 Like

Unfortunately, there is not. There are options, but they tend to be specific to how the load is being applied and how it is being reacted.

Here are some hints which may or may not be useful :slight_smile: :

If a body velocity is unchanged then the net forces = 0

If velocity changes then the net forces = mass * acceleration.

A body at rest will exert a force = m * gravity and the body it rests on will exert an equal and opposite force.

If you have a change in energy then force = energy / displacement

You can use a fixed joint and Joint.currentForce / Joint.currentTorque to get the constraint forces, be aware of the relative inertia of the two bodies if load is applied rapidly - I’m not sure how PhysX will deal with that.

You can use a spring and measure the displacement to reverse the force out of the spring properties.

Unity - Scripting API: Collision.impulse to get contact forces.

3 Likes

There is no built in method, and no easy method either.
If you seriously need that, you would have to register all forces you are adding to your body during frame and add to it force generated by gravity.
Preserve velocities of rigidbody and calculate expected velocities that body will have next frame.

In the next frame you compare preserved velocities and current velocities and with usage of fixedDeltaTime you can calculate acceleration that happened on the body since last frame.
Since you have accelerations calculating forces is a cake now.

ps. naturally you have to do it for force and torque separately.

1 Like

Man I can’t believe that there is no built method, I can think of a thousand times when I would want that. Thank you guys for your help anyway!

3 Likes

It’s not really as useful as it seems: If the rigidbody has changed velocity, then you know the acceleration and you know the net external force that has acted upon it. If it has not changed velocity then there was no net external force.

It is useful to know individual external forces and that is where you have to chose your methods, depending on use case.

1 Like

Unfortunately you are not completely right.
Body can be resisted by another body and from it’s changing velocity you cannot deduce what are the true acting forces.
Simple example is body on a plane and gravity - since body is not moving there should be no acting forces.

I think that is exactly what I said. If there is no change in velocity then there is no net external force. There are two external forces, mass x gravity and the reaction force of the plane, they are equal and opposite.

Edit: To clarify, that is why I said it is more useful to be able to get individual forces.

3 Likes

Unfortunately, Joint.currentForce / Joint.currentTorque also returns the net force applied to the rigidbody, so it has the same usefulness. For example, if a joint is applying a ton of force but the rigidbody is steady (no velocity changes), Joint.currentForce will return zero.

Oh, that’s not very helpful. So is there no way to get transmitted joint constraint force?

If your joint is a spring perhaps you could calculate the force out of the spring rate and the displacement from the target position. But I haven’t tested it so I can’t tell if/how this would it work.

Just wanted to leave a note here. Not a solution for the original problem though.
But I tried to search for the same thing but for Rigidbody2D and it led me here.

At least for Rigidbody2D, using joints seems to be the correct answer.
The base Joint2D class has GetReactionForce(float) which returns a Vector2, the amount of force it’s applying to the rigidbody to maintain the joint.

For example, you hang a rigidbody on a static anchor with a SpringJoint2D
When the system stabilizes, there’s a baseline amount of force it applies to counteract the weight of the rigidbody. Dropping an extra weight on it will stabilize to the weight of both.

So if you wanted to detect “extra weight”, you’d have your script calibrate to the weight without anything on it, and react to when that baseline is exceeded.

This works even with FixedJoint2D. So you could have some kind of non-moving floor panel that can detect being stepped on or weighed down by objects.

It kinda sucks that a similar API doesn’t exist for the 3D components.

You mean these as mentioned above?
https://docs.unity3d.com/ScriptReference/Joint-currentForce.html
https://docs.unity3d.com/ScriptReference/Joint-currentTorque.html

I’m not an expert in 3D but from what was said above, it would seem these can return zero in the circumstance you describe. I wasn’t aware of that difference TBH.

The only difference in 2D is that there’s an additional set of methods to calculate it in a specific time-step rather than the default Fixed timestep. AFAIK in 3D the above properties are the historic “what was last applied”.

For 3D, there is also a new method called GetAccumulatedForce (and torque) which returns force that has been applied to the object so far (by AddForce) in Newtons. Although, keep in mind that this only accounts for user applied force, not gravity, collisions, etc.

5 Likes

I have a similar problem, an object at rest will have gravity, an object resting on each other will exert their weight force.

(For purposes of determining things like points of fracture, and identifying/anticipation structural degradation, of warping patterns, such as in simulating the structures of a house against time and the forces of nature, etc)

Starting attempt at getting this weight force is using triggers slightly larger than your object and getting the direction of the trigger hits relative to object, if trigger hit is above, get triggering objects gravity and add it to objects net force applied to it. This of course doesn’t go far enough without having center of mass or surface area, but It’s a start.

Thank you for giving me this information

Conclusion: Joint.currentForce is useless; it just returns a change of the Rigidbody’s momentum (no change in velocity? returns 0).

Sadly, though, it doesn’t even seem to do THAT. No matter how I configure the joint, regardless of whether the rigidbody moves or not, it ALWAYS returns 0.

Man, looking at the PhysX API and seeing what COULD be but simply isn’t is extremely frustrating. Virtually all the information you could ever ask for from a physics engine is there. Sometimes I wish I could just join Unity to implement this stuff properly or develop some kind of hack wrapper to bypass Unity’s shoddy wrappers and access the PhysX API directly.

Just for fun, I’m going to start a list here:

  • Joint.currentTorque and Joint.currentForce either a) always return zero thus is useless, or b) only return net changes in momentum, thus is useless because this can be done by comparing the rigidbody’s previous velocity and angular velocity to the current.
  • Joint.connectedBodyAnchorRotation is not exposed. This creates all sorts of bugs (reactivating a game object causes its joints to drift from their original rest rotation) and makes player-editable joints a huge pain to implement.
  • Collision.impulse does not include friction forces; there is no way to get force applied due to friction. Formerly, there was frictionForceSum and even prior to its obsolesence it never returned anything other than 0.
  • There is no efficient way to query joints are connected to a rigidbody. Specifically, if Rigidbody A has a component Joint that connects it to Rigidbody B, there is no simple way to get that Joint from Rigidbody B; you need to find all joints in the universe first and examine each one individually or write some kind of bug factory script that you have to remember to attach to every rigidbody that is referenced by a joint.
3 Likes

Which is why we don’t fall through the floor in the real world. Since the amount of electromagnetic repulsion between us and the floor is just the same as the gravitational force applied, the net force is 0. Whatever value you set as the gravity, subtract it from the net force and you’ll get additional forces applied to the rigidbody.