Search Unity

How to find the force being applied to a rigidbody

Discussion in 'Physics' started by KevNicholson, Mar 4, 2021.

  1. KevNicholson

    KevNicholson

    Joined:
    Feb 17, 2021
    Posts:
    18
    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.
     
    MaxLohMusic likes this.
  2. AlTheSlacker

    AlTheSlacker

    Joined:
    Jun 12, 2017
    Posts:
    326
    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 :) :

    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.

    https://docs.unity3d.com/ScriptReference/Collision-impulse.html to get contact forces.
     
    Last edited: Mar 4, 2021
    danilofaugusto and KevNicholson like this.
  3. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,073
    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.
     
    KevNicholson likes this.
  4. KevNicholson

    KevNicholson

    Joined:
    Feb 17, 2021
    Posts:
    18
    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!
     
  5. AlTheSlacker

    AlTheSlacker

    Joined:
    Jun 12, 2017
    Posts:
    326
    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.
     
    MrBigly likes this.
  6. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,073
    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.
     
  7. AlTheSlacker

    AlTheSlacker

    Joined:
    Jun 12, 2017
    Posts:
    326
    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.
     
    Last edited: Mar 4, 2021
    laranthir, MrBigly and arkano22 like this.
  8. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,508
    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.
     
  9. AlTheSlacker

    AlTheSlacker

    Joined:
    Jun 12, 2017
    Posts:
    326
    Oh, that's not very helpful. So is there no way to get transmitted joint constraint force?
     
  10. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,508
    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.
     
  11. Pharan

    Pharan

    Joined:
    Oct 28, 2013
    Posts:
    102
    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.
     
  12. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
    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".
     
  13. Augustinas-Simkus

    Augustinas-Simkus

    Unity Technologies

    Joined:
    Mar 9, 2020
    Posts:
    84
    Doggy88, Celezt, INeatFreak and 2 others like this.
  14. Kemordia

    Kemordia

    Joined:
    Oct 14, 2018
    Posts:
    1
    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.
     
    Last edited: Jun 21, 2023
  15. Tutoroot

    Tutoroot

    Joined:
    Feb 1, 2023
    Posts:
    7
    Thank you for giving me this information
     
  16. Zergling103

    Zergling103

    Joined:
    Aug 16, 2011
    Posts:
    392
    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:
    1. 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.
    2. 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.
    3. 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.
    4. 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.
     
    Last edited: Feb 24, 2023
    Edy likes this.
  17. ghj7211

    ghj7211

    Joined:
    Dec 28, 2020
    Posts:
    1
    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.