I’m an experienced dev making a realistic ping pong game in Vive.
I’ve generally had to work around Unity physics in my character-based games, but since ping pong has 2 rigidbodies (ball and paddle) and 3 static boxes (floor, table, net), I wanted to give it another try. (and an AI trigger box)
Unfortunately, continuous collision still fails at high speeds. (It reports the collisions, but its collision normals are necessarily imprecise, and bodies often fail to change each other’s angular velocities)
Discrete collision works with realistic precision when physics clocks around 1000hz (and a dozen of Unity’s baby glove settings are nerfed) when the paddle moves slow, but pros swing in the 20-30m/s range, the ball gets to around 20m/s when they smash it, it has a radius of 2cm… so we ran tests at 5000 and 10000hz. They all felt the difference, but the cpu on a decent VR machine still starts to miss frames over 5k hz. Obviously, my 2 fixedupdates have been stripped down already.
I don’t have source for u5 or physX 3, so I’m asking if there are any simplifications I can make to optimize the setup or teardown of the physics and collision loop, for such a simple situation?
you probably want to run physics at a normal VR rate - say 90hz or 120hz, and check if ball is behind paddle each frame while recording a snapshot ie velocity, position.
Then, (this is trickiest part) use the velocity of the ball as a ray from the last known position when it was in front of the paddle. This way you have a before and after snapshot and can a) figure if it collided or not with a sweep test, and b) have enough data to construct a decent response.
That’s how I’d do a hybrid for tennis, pong or cricket.
If the normals are the problem then this is incredibly trivial to work out. You only have a single ball normal (it’s velocity normalized) and you already know the normal of the bat… easy to assign a new velocity from this reflected vector.
Physx will never be the physics engine for accuracy, it’s not designed for simulations of high accuracy to begin with, but this doesn’t make it useless.
There’s also the question of why your normals are messed up. How are you moving the paddle? is it with rigidbody.MovePosition and rigidbody.MoveRotation? it HAS to be or it won’t be internally updated in physx engine. If you’re just setting transforms, then that’s the first problem why it’s passing through or giving bad normals. It might not be the only reason, but it’s one reason.
Finally, you probably should do all/any velocity calculations and assignment within FixedUpdate.
The paddle is simulated with velocities so that every visual ticks its movement is spread out over my many physics ticks. It appears parented to the controller but doesn’t break the laws of physics.
I am getting amazingly good results at high hz when the users play conservatively. Top players can pick a small point on the table and use realistic spins to hit it. I’ve written several physics systems over the years… a few in Unity, so I know how I would do my own. Its just that its so close to realistic, I’d almost rather optimize the source for my specific application.
You might want to tinker with iterations, contact offset, bounce threshold, thicker paddle collider, all that stuff. It’s best to experiment at this point - which I’m sure you’ve tried. I guess the paddle is made up of several convex mesh colliders?
The thing I don’t understand are the bad normals and imprecise velocities. Is there a pattern to it? perhaps it’s a grazing angle or just too much velocity? sounds like in this situation it may have still penetrated the paddle and unity does a best guess.
If you’re really out of options at that point you probably could try this:
at collision, move the ball back by its original velocity to precisely the point where it will have impacted, and move the paddle to where it would be with the velocities it did have.
the idea is we turn back time and resimulate it but the difference being the ball is at a reliable position. It’s a band aid. I think you’d probably be best off integrating physx dll yourself, with your own fixed timestep. You don’t need this threaded, it won’t get faster threaded with so few items in play so perhaps integration is pretty simple?
Thanks Hippo. I was hoping maybe someone had access to the source for the unity wrapper or physX3. I think you’re right that I would need to do it myself.
I’m doing a realistic simulation so the transfer of angular vel based on rel vel and the ang vel of the paddle at the point of impact are the juicy bits to calculate.
The imprecise data in continuous collisions is due to how swept volumes approximate the collision. We rewrote it for a product on Unity 4, but that had a budget to cover it.
This won’t really help. (And neither will the OP’s goal of raising the Unity physics to crazy-high levels).
The physics/FixedUpdate loops aren’t spread out evenly over a second. If you have physics at 200Hz, you aren’t getting a call to FixedUpdate every 1/200th of a second.
Rather, Unity is doing all of its rendering/Update stuff, and then when it gets to physics processing it advances physics time 1/200th of a second, and simply repeats that process if physics time is still not caught up to realtime. You’re going to get big clumps of physics processing between rendered frames when physics is much higher than graphics frame rate…