Apologies for the lack of updates of late, I’ve been struggling with physics stuff for a while, and I also had a pretty bad flu a few weeks ago which slowed me down a lot! However, I’ve now finally made some good progress on the physics front, much improving the way gears and motors work.
For the gears to work, we want neighbouring gears rotate in sync with each other, taking the ratio of their respective diameters into account. My old implementation for this synced neighbour gear’s angular velocities, but didn’t sync angular displacement (so gears would slip under high torque loads), and didn’t take rigid body inertia tensors into account (particularly noticeably wrong with gears that were part of rigid bodies with large moments of inertia).
The proper way to do this is to have a physics constraint that forces the angular velocity and angular displacement to stay in sync. Unity comes with a configurable constraint (or joint), which is almost flexible enough for what I need, except that you can’t specify any kind of gear ratio. PhysX 3.X supports custom constraints, but Unity is still using an old version of PhysX (2.8.3 I think). So I had to implement my own constraint, which gets applied in FixedUpdate to modify rigid body angular velocities. This works OK for the angular velocity part of the constraint, but because I don’t have access to the internal physics update code, I found it problematic for syncing angular displacement. This is because Unity doesn’t provide the current total angular displacement of a rigid body. I attempted to track it myself, but because I don’t have direct access to the changes made by the physics update, it was not accurate. So instead, over every update, I accumulate an angular displacement delta between the two rigid bodies using their respective angular velocities, and then use that to apply a correction back to their angular velocities. This isn’t as good as syncing the angular displacements directly, as it means the gears still slip under high torque loads, but they do eventually correct themselves with a kind of delayed “springyness”. At least now they won’t slip indefinitely, so it’s certainly better than my old implementation!
As Unity physics doesn’t “know” about my gear constraint that is modifying angular velocities outside of the main physics update, the built in joint motor no longer worked properly. So I had to implement my own motor constraint (which was pretty simple because it only constrains angular velocity, not displacement). An added bonus to doing this was that it gives me much more control, and I was able to add a torque curve that makes the motor behave more realistically, and can be customised for all different kinds of motor.
Also, now that the new gear constraint properly accounts for rigid body inertia, I was able to increase the motor torque to a much more reasonable level, and have it behave consistently regardless of whether gears are part of large or small rigid bodies.
Well, that’s it for now, these changes are now in the playable build. Hopefully they’ll allow you to build more complex and interesting machines!