- Home /
AddTorque does not use ForceMode as expected (Different than AddForce)
Currently using Unity version 2018.2.5f1
If a rigidbody has a mass of 1, ForceMode.Force and ForceMode.Acceleration should be the same, right? This appears to be so with AddForce, but not with AddTorque. ForceMode.Acceleration results in less torque than ForceMode.Force. Is this intended behaviour? I'm not familiar with the math.
Answer by roddles · Aug 21, 2020 at 02:12 AM
While force, F = m × a, torque, T = I × α, where I is the rotational (the moment of) inertia, and α is angular acceleration. For a very simple point mass, I = m × r², but for objects that have mass and volume, (without getting deep into the physics), there is instead an inertial matrix (formally the inertial tensor), in which each component of the matrix represents the resulting inertia on a combination of two axes: the axis of rotation and one of the three cardinal directions. Thus a group of three components for a given axis of rotation indicate the inertia in the x, y, and z directions.
So, on to Unity's torque implementation, the rigidbody component includes an inertialTensor
member variable. If the inertialTensor
is not manually set by script, Unity will automatically calculate it using information from the collider and store it in inerntialTensor
, which will be used when calling ApplyTorque -- with a forcemode that includes mass -- to find the angular velocity vector.
To bring all this together: whereas AddForce and ForceModes take into account just mass, AddTorque and ForceMode must take into account Inertia, which as you can see from above, is an entirely different beast that depends not just on mass, but also the shape and dimensions of the object's collider.
HTH.
Wow, I wasn't expecting an answer after so long. Thanks! I can barely remember what I was trying to do. That helps me understand what's going on a bit better, but I was comparing not just with a mass of 1 but also the same collider with the same shape and dimensions. So wouldn't the inertialTensor be calculated the same? I'm pretty sure it was under these conditions that Force$$anonymous$$ode.Acceleration resulted in less torque than Force$$anonymous$$ode.Force. Exact same object, just changed the Force$$anonymous$$ode. I was using 2018.2.5f1 so if it was a bug maybe it's been fixed by now.
Yeah, I answered just in case someone else came along and had the same problem.
So, the difference is that when you call AddTorque()
with different force modes, the way the angular acceleration is calculated will be different. With Force$$anonymous$$ode.Force
, you indicate that the "force" parameter to AddTorque is a torque, so it needs to calculate angular acceleration using the formula, α = T / I, whereas with Force$$anonymous$$ode.Acceleration
, you indicate the parameter is the angular acceleration, α, so there is no adjustment made to the value passed in.
In the end, I found that torque and angular acceleration for my project was overly complicated. Instead I just started applying the angular VELOCITY that I wanted directly, without accelerating from 0 to my desired angular velocity and then decelerating back to 0 just in time to hit the correct heading with zero angular velocity. It's just not really necessary unless you have extremely massive objects and need those very realistic physics.
I do this by:
Calculating the delta in angular velocity I need using an equation like
targetAngularV - currentAngularV
, the former you will need to calculate, the latter is available from the rigidbody.Clamping this value to a maximum angular velocity e.g.
$$anonymous$$athf.Clamp(deltaAngularV, rigidbody.maxAngularVelocity)
Passing this delta of angular velocity to
rigidbody.AddTorque(deltaAngularV, Force$$anonymous$$ode.VelocityChange)
I find this far easier to manage, and is very similar to the way most games feel.