AddForceAtPosition (physics) broken in unity 6

After upgrading to unity 6 I noticed that something with physics changed - most likely AddForceAtPosition method. I have made vehicle suspension system based on raycasts and also “recoil” like force using the same function, and it seems like force is 2-3 stronger than before.
My vehicle seems to sway from recoil like crazy.

I wonder if there is anyone else who noticed something similar? The most important thing I want to know is if previous behaviour was invalid and it has been fixed, or current one introduced bug.

Update - AddTorque and AddForceAtPosition were calculated in a wrong way in all previous versions for VelocityChange and Acceleration mode.

Answer from support:

In 2022LTS (and previous versions) the AddForceAtPosition method had its VelocityChange/Acceleration modes artificially introduced. Physx does not support these modes (for that logic. force/impulse only) as such we converted those values to force/impulse internally and then passed to Physx. The angular velocity conversion was being computed using mass rather than the inverse of the inertia tensor matrix, which was incorrect. This is why their angular velocity is no longer matching what it used to match in previous versions. This change also affected AddTorque.

The other functionality that was affected by the changes include: AddExplosionForce, AddTorque and AddRelativeTorque methods.

So how should one go about tackling this - just fiddling with force values until you get a result that feels similar to what it was before, or is there some actual mathematical conversion we can do to get the exact same results as before?

I kind of doubt there is way to get exactly the same behaviour as before (by using the same function), because calculations are done differently. In theory you can manually try to reproduce previous one, but personally I don’t know the formula.
You could try to create ticket if you really need that, and maybe they can help you reproduce old calculations, otherwise you just need to adjust values as much as you can.

1 Like

It’s probably possible to calculate the “closest” equivalent. However an exact conversion is in most cases not possible as the moment of inertia may be different for certain axes. When they just used the mass value directly to “scale” the force, that scaling would be the same for each principal axis. So in cases where the object is not perfectly symetrical in all directions (so not a perfect sphere or cube) you generally get different behaviour around different axes.

Though to even approach a closest fit conversion we would need to know exactly what they did in the past. Since rotational motion and force based controls are generally hard to predict, the trial-and-error approach would probably be easier.

1 Like

To get the exact same behavior as before, just use ForceMode.Force and multiply the input value by rigidbody.mass

This should work for AddTorque, but I kinda doubt it woud work for AddForceAtPosition. AddForceAtPosition may add linear force as well as a torque depending on the position where it is applied. If you multiply the force by the mass you would also affect the linear force which would be way stronger (assuming a mass > 1). The bug was only in the torque part. Though I can’t really test any of that at the moment.

An update:
I ended up getting in contact with a Unity engineer that works on the Physx side of things.
They suggested the following change:

body.AddForceAtPosition(force, ForceMode.VelocityChange);

to

body.AddForceAtPosition(force * body.mass, ForceMode.Impulse);

Which in my case worked perfectly.

2 Likes

Thank you!! After I updated my project to 2023.2 suddenly all aircraft models were spinning around when using the rudder, while the same code worked fine in 2019.4.

Your solution works perfectly and solves all of the issues!

What did they change? Because obviously this has been a bug since 2023, are they going to fix it?

No worries! The reason for the change is detailed further up by Qriva. Basically, the way it works in Unity 2023 and Unity 6 is physically correct, while in previous versions it was wrong. So it probably won’t change back to how it was before.

1 Like