Physics independent of the Framerate: using substepping but not working

Hi everyone,

I got an question about how to make Physics computations independant of the framerate of the game.

I have one actor, a bouncing ball that have an impulse apply to it every tick to compensate the gravity. And when close to the ground, it receive a big impulse to make it “bounce”.

But the catch is that the final result will be very different depending of the framerate :
485116fa2d4edabb9f4577f895815fe10c73427bfd997b36ea45e9995f6466f3943ee1216bfa0db3dc2e47b6674e6231

As we can see in these 3 gifs, in the first case with no restriction on the FPS, the ball is perfectly bouncing and slowly falling.
In the second where I limit the max fps to 30, sometimes we only have half of a bounce. And for the third with a limit at 10, we only have small bounces and the ball could stay on the ground for a time.

On my side on the code, I looked at the Substepping physic system to have something that should be independent of the framerate. Here the snippets :
https://dev.epicgames.com/community/snippets/lNw/unreal-engine-physics-with-substepping-setup

( I know that there is also a way to register every ticks the substep’s method on the body instance of my StaticMesh, but this way from the BeginPlay seems more ideal and I didn’t see any differences. )

So, from that I would thought that every thing should have been identical no matter what the number of FPS were. I don’t think I forgot to enable something on the project settings either :

Here are the source I had on the topic :
http://mansisaksson.com/view/ue4-substepping

You will noticed that I don’t multiply the impulse with the delta time on the “counter gravity”. I don’t understand why but it seems that we don’t have to use the delta time in our physics tick computations.
I have tried with both anyway, and it didn’t change anything.

So, does anyone with good physics knowledge could help me ?
Thank you everyone =)

I made one discovery.

I displayed the DeltaTime that I have on the screen to see if it was indepedant of the framerate.
When I set the limit to 30FPS, my DeltaTime is always 0.033333, and when sets to 10FPS it’s 0.1000. Which is exactly the inverse of the number of FPS, which proves that the substepping system is not working at all. And I don’t understand why =/

Delta time IS the frame rate :slight_smile:

In the default Tick function yes, but still in the StepStepping one ? They don’t have their own delta time ?

How can I fix my code ?

Do you mean the tick node running in a blueprint with substepping enabled?

I thought substepping applied to the physics, but assumed that the tick node remained the same.

Sorry, I have no idea about how to fix the physics issue…

I code in c++ but it would be the same if I had made it available to BP.

Another tried that I made is to create a counter of substepping.
In my Substepping tick I add +1 to my counter and on actor tick I display this counter and reset it.
It always display 1 :
image

And yes, I did enabled the smoothed framerate :

Yes, it is strange.

I assume you also followed the rest of that article, and worked with the ‘body instance’.

( I’m not checking, I actually assume you did ).

My source code is available here :

And thank you for taking time to help me ^^

Sorry, should have kept my virtual mouth shut :zipper_mouth_face:

I just noticed your comment about tick and frame rate. And that’s exactly what you would expect.

I took a quick look at the code, but don’t see anything standing out.

Hello there !

I come back to my post to share a solution that I found.
It seems that AddImpulse is not working with substepping, but AddForce is !

Looking at the declaration of the methods, it seems that only methods taking a bool bAllowSubstepping can be used that way (make sense).
image

As I am already in an “Substep context”, I have to not allow Substepping when calling the methods, and it works.
image

Finally… my counter is still displaying only one substep by tick whatever the FPS limit I set… but it works so I’m not worry.

Excellent! :sweat_smile: