I’m trying to follow this guide (using substepping and
AddCustomPhysics) for framerate independent physics in a ball rolling game, using
AddTorqueInRadians on a spherical mesh.
I have followed the guide exactly, including project settings, yet the speed (caused by the ball rolling on a flat ground) is slightly different depending on framerate, with it being slower in higher resolutions, compared to lower resolutions and quality.
Code for rolling, simplified for ease of testing, (
PhysicsTick_Implementation from the guide) is as follows:
MarbleMeshInstance->AddTorqueInRadians(FVector(0, speed * 10 * SubstepDeltaTime, 0),false, true); //MarbleMeshInstance is an FBodyInstance
I have also tested with just
FVector(0, speed * 10 , 0), but it also is still framerate dependant.
I am also doing substepping and there is no way to achieve frame independent rotation.
AddAngularImpulseInRadians(rotation * DeltaTime), true) done in substeps should give same result @60 fps and @30 fps but it doesn’t.
I also tried AddTorqueInRadians() inside and outside substep function without success.
It looks Unreal can’t do frame independent simulation.
It is supposed to be used without the deltatime.
It works that way, you have to have a mistake elsewhere, since I use that just fine in my project that is heavily based around this kind of physics. I’ve directly tested that my forces and torques take the same time in 60fps, 20 fps and 2 fps.
To add to @nitrooo: impulses are meant to be applied once. If you were to apply them in each frame, you should use deltatime, but you are doing it wrong. You add forces that are timed automatically or you add impulses once, when it’s bullet impact or something.
The general consensus is that Unreal is unable to do perfectly framerate independent physics.
To minimise the changes of framerates, I used
AddTorqueInRadians without multiplying DeltaTime inside of
PhysicsTick_Implementation, then in Settings > Physics > Framerate:
- Max Subsep Delta Time:
- Max Substeps:
This seems to work well between 20fps to 60fps. I am unsure if this works correctly for higher or lower framerates.