How to make physics forces independent of frame rate?

I’m trying to apply a physics force every frame to my object. I noticed that functions like AddImpulse and AddForce make the object move at different speeds depending on the frame rate. Multiplying the input by the delta time makes the object move faster the lower the frame rate. Not using delta time, as you would expect, makes the object move faster at higher frame rates. I tried using the Physics Thruster component but it has the exact same problem. Is there a way to apply physics forces every frame and get the same speed regardless of frame rate?

2 Likes

DeltaTime should work, can you paste sample of code where you use it? There no way around delta time really because UE4 updates postion on every frame, so you need time diffrence between them

I don’t think the problem is with my code, because the Physics Thruster component has the same behavior as my code. I use the delta time like this:

Mesh->AddImpulseAtLocation(Impulse*DeltaTime, Location);

Functions like AddForce are framerate independent. When you apply a force of 10 on an object with mass 1, the object will experience an acceleration of 10 cm/s^2 for the duration of the frame.

This means if the frame took 3 seconds, the final velocity will be 30 cm/s. If the frame took 2 seconds the final velocity would be 20 cm/s

Typically forces are applied over multiple frames for some period of time, and so this is what you want since applying a force for 3 seconds should produce the same change in velocity regardless of the frame rate.

An impulse allows you to change velocity instantaneously. You can think of this as a force applied over some period of time. An example of this may be that an object is pushed on for exactly 0.5 seconds. In this case if you applied a force you would not get the correct result unless the frame rate happened to be exactly 0.5 seconds. So in this case you can calculate the impulse as 0.5s * (the force you’d apply) and PhysX will change the velocity accordingly.

Hope this makes sense, let me know if you have further questions.

Thank you, that helps a lot. However, I think I’m still missing something. I’m trying to make simple vehicle suspension by raycasting down each frame, then applying an upwards force as well as a damping force based on the raycast distance. Here’s the code I’m using for each wheel to apply the force:

void ASimpleVehicle::WheelForce(float Compression, float PrevCompression, FVector HitLocation) { FVector SuspensionForce = SuspensionStiffness*Compression*GetActorUpVector(); VehicleMesh->AddForceAtLocation(SuspensionForce, HitLocation); if (Compression > 0.f) { FVector DampingForce = (Compression - PrevCompression)*SuspensionDamping*GetActorUpVector(); VehicleMesh->AddForceAtLocation(DampingForce, HitLocation); } }

I get nice bouncy suspension at the default 120 FPS in the editor. But if I type t.MAXFPS 30 or 60 into the command box, the suspension becomes very stiff. This is not at all frame rate independent like I want it to be.

Sorry about the code formatting, not sure why it did that when I pasted it.

It’s not possible to make your physics behave identically regardless of physics simulation frame rate. You can make it independent of the rendering frame rate, but all computer physics simulations are dependent on their time step. This is because game simulation of physics is done by calculating discrete chunks of time and integrating the results (known as Numerical Integration, you can google it for lots of details). The problem is that large time steps cause most integration methods to overestimate forces and movement, which you’re seeing in your game when you increase the time between updates and your suspension responds with much more force than when the time step is small. This is why many game engines have a fixed physics time step that is updated separately from the rendering loop. I don’t know if unreal has the option to configure physics timestep and rendering framerate independently, but no matter what, changing your physics timestep will always change the results of your simulation.

Here’s a quick example:

Say you’re applying 10N down the x axis to a 1kg object for two seconds. This means a = F/m = 10m/ss.

@ .5 fps (2s per frame)
Frame 1, 2s: v = 2s * 10m/ss = 20m/s. pos = 2s * 20m/s = (40m, 0m, 0m)

@1 fps (1s per frame)
Frame 1, 1s: v = 1s * 10m/ss = 10m/s. pos = 1s * 10m/s = (10m, 0m, 0m)
Frame 2, 2s v =  20m/s. pos += 1s * 20m/s = (30m, 0m, 0m)

@2 fps (.5s per frame)
Frame 1, .5s: v = .5s * 10m/ss = 5m/s. pos = 5m/s * .5s = (2.5m, 0m, 0m)
Frame 2, 1s: v = 10m/s. pos += .5s * 10m/s = (7.5m, 0m, 0m)
Frame 3, 1.5s: v = 15m/s. pos += .5s * 15m/s = (15m, 0m, 0m)
Frame 4, 2s: v = 20m/s. pos += .5s * 20m/s = (25m, 0m, 0m)

Note that after two seconds velocity is always 20m/s but the position is wildly different.

If you absolutely need your suspension code to use a predictable fixed time step, you can use your own fixed simulation time always, no matter what the frame time was. If the frame time was much longer than your chosen fixed simulation timestep, run your suspension simulation multiple times that frame.

void DoSuspension (float dt) {

const float simStep = 1.0f / 120.0f;

float timeToSimulate = dt + m_prevFrameExtraTime;
for (; timeToSimulate > simStep; timeToSimulate -= simStep)
    Simulate();
m_prevFrameExtraTime = timeToSimulate;

}

Hope this helped!

jmassey is spot on. One thing you could try is turning on sub-stepping which will tick physics at a higher rate. In the settings you can control how small you want to make each sub-step so you can render at 30 but tick physics at 120, though this might be quite expensive.

If you go this route and want even more accuracy you’ll want to apply forces at the sub-step level. If you look at the vehicle code we actually do this, but the way we do it is not very extensible. There is a plan to make this a more generic system that you can plug into, but that won’t be in for a little while.

Very informative post, thank you. I’m targeting Android with this particular project. I wanted to run at 60 FPS on high-end devices but let lower end devices run at a lower FPS while maintaining the same physics behavior. Maybe I should simply cap the frame rate at 30 and make sure the FPS never drops below that. Would that be the easiest way to ensure consistent physics behavior?

I’m pretty new to UE4 so I’m unaware of all of its capabilities, but as Ori suggested you can try using physics substepping.

Here’s his blog post on it

You can try leaving your physics at a constant 60fps and reducing the overall framerate to 30 when you detect a low-end device. With any luck that’ll just work. Beyond that you might have to get into custom solutions specific to your project. Perhaps an easy thing to do would be to a table of force values for your suspension based on frame time to compensate for the expected overestimation. If the vehicle in question is the most important part of your game and you can afford to spend extra cycles on it, then another (more complicated) solution could be custom physics code for your vehicle where you do your own small time step force calculations and set the position of the vehicle manually. I’d definitely recommend starting as simple as possible and working towards more complexity/optimization only as needed.

One approach would be to modify the way sub-stepping works so that instead of slicing the time into steps it uses a timebank. We didn’t do this in the engine because of the implications on blueprints where they rely on delta time to be representative of the real passage of time.

Using a timebank you tick at a constant rate every time, and you simply have frames where you do not tick at all or you tick multiple times. This will require some modification of the sub-stepping code though, so I wouldn’t recommend it unless you’ve tried the simple approach and it’s still not accurate enough.

This article better explains the details: http://gafferongames.com/game-physics/fix-your-timestep/

Substepping seems to do the trick. I’m getting much more better results with it on. Hopefully it won’t affect performance too much, especially since my game is for Android. Thanks for help!

Hello Ori
In my situation i’m having bouncing object and every time i’m running the simulation, i’m getting difference results. Do you think in 4.5 there will be improvements in such cases as ours.

I’m primary using blueprints but sometimes 1-2 rows of code :slight_smile: (very basic)

Can you explain further how to set exactly the sub-stepping to get the best possible results when simulating physics.

I didn’t get what you said about AddForce and that is actually is independent.

When you apply a force of 10 on an object with mass 1, the object will experience an acceleration of 10 cm/s^2 for the duration of the frame.

1.How to apply force of 10
2.How to set the duration of the frame-rate.

if you can answer all that it will be great, my goal is to have same angle, speed of the bounce object every time i run the simulation.

Any Help is greatly appreciated !!!

Regards

To turn sub-stepping on go to project settings and look under physics. There is an option to enable sub-stepping. In here you can also set the max number of sub-steps and the max sub-step size. You shouldn’t have to edit these though as I believe it’s already set for 60fps.

I’m curious what effect you are trying to achieve as I might be able to give you a better strategy depending on the details.

Let’s look at a simple case of making a simulated cube hover. To do this we must add a force that will counteract gravity. AddForce uses units of kg * cm / s^2

Since F = mass x acceleration and we want acceleration = 980 cm/s^2 we must multiply 980 by the mass of our object to get the needed force. So let’s apply this force every frame by adding a tick event and calling AddForce (mass * 980) on our simulated object. When you run the game you should see the object is completely stationary as it will experience 0 net force.

You’ll note that we didn’t use delta time as the force of gravity and the force used by AddForce both account for delta time implicitly. In this case, if we had used an impulse we’d have to account for delta time to match acceleration due to gravity.

One other thing to note about using delta time. In order to keep physics simulation stable we actually cap the delta time passed into the physics engine. This value can be changed in the physics settings of the project, but you can see that by default any FPS worse than 30 will get capped (when sub-stepping is turned off). This is why sub-stepping can help as it will allow you to maintain the real delta time when framerate gets bad. Because of this it’s always a good idea to use AddForce instead of AddImpulse unless you are working with a case where the time a physical interaction takes is known (for example how long a collision between two cars took)

I hope this helps, I realize it’s a bit confusing

Hi. I am struggling to understand how a variable physics time step can work for multiplayer (I am familiar with BulletPhysics which uses a fixed step). How would a racing game for example? If the frame rate determines the distance a car can move in a given time, as jmassey describes above, would the player with the lowest framerate win the race?

On a related note, does UE4 have client side prediction, because if the server has a low framerate, would the clients see players jerking?

Ori, you mention a fixed step would require “some modification of the sub-stepping code”, please could give us some pointers (function names) in the engine where this modification code be made? Do you foresee Epic providing an option in future to enable switching the engine to fixed step - I would imagine this would open up the engine to simulation applications?

Thanks

PS. I am using the engine (I love UE4 btw, great work) to create a physics based helicopter.

In the multiplayer case you would want any win logic to be done on the server side to prevent cheating. I would expect that you’d run the simulation on the server, with clients running their own local simulation to reduce the lag feeling.

You would need to sync these in some way, though I don’t think we have support for this on the physics side as it varies on a per game basis. In the case of a racing game you’d probably want to come up with your own solution. If you look at some of our vehicle code you can see there’s custom code written for replication.

The substepping is done inside FPhysSubstepTask::StepSimulation
If you are OK with the physics simulation time being different than the delta time content creators see you could simply ignore the DeltaTime passed in and just grab the value from some project setting. Note that any content that relies on DeltaTime will be wrong.

If you want to change it so the actual delta time passed in is fixed for the entire engine take a look at UEngine::UpdateTimeAndHandleMaxTickRate which already has some logic for fixed timestep (bUseFixedTimeStep) which you could modify to fit your needs.

Hope that helps

That’s excellent, thanks Ori, I will take a look.

I’m not familiar with what unreal has built in for multiplayer but its very possible to sync clients running at different framerates by always blending towards the owner’s broadcast information about a given actor. Prediction / local simulation still helps fill in the gaps and you generally don’t see too much glitching. Personally I dislike control / simulations being run on the server preferring the direct feeling you get when minimizing lag between control input and result (even in a good scenario you have to be careful to minimize the lag induced by control system-> physics simulation → rendered result). Having win logic negotiated by a central server certainly makes sense though!

I have very simple 2d platformer game and I couldnt achieve fixed velocity on spawn items on different fps. My project is based on blueprints. And my character spawn items from his inventory. Can someone help me please how can I made this? I am using delta time, on event tick i am dividing by 1, my delta time works perfect with character jump and other things, such as enemy movement.But I couldnt achieve fixed velocity on add impulse or add force when I spawn an item… Can anybody help me about it? If I use projectile movement my item direclty goes down without collision.