Game Dev

Everything you always wanted to know about Unreal Engine physics (but were afraid to ask)

So you have created a physics based game in Unreal Engine 4, you have put some spring models here and there and you are testing the game at 60fps in your development machine. Now you are wondering what your game physics would look like if the game run at 30fps, maybe because of a frame rate drop or a vsync clamping on a low-end machine. Then you try to make a test; you open the Unreal Engine console and type t.MaxFPS 30. Chances are that your game will run fine for some time, then it suddenly explodes. What’s happening?

Fixing Your Timestep

If you are a bit familiar with physics engines architecture and the underlying math (numerical analysis[a]), you know that the evolution of a numerical physics simulation is very tied to the timestep of each iteration; the smaller the time step, the lesser the error and vice versa. Moreover, whatever integration method your physics engine is using, there will always be a region of instability[b] for your physics model that depends on the timestep. The larger the time step, the more unstable is the system. That’s why your springs explode at 30 fps if you tune their proportional constants at 60 fps[c]. Here I’m taking spring models as an example for their wide use in game physics, but you can also experience instability when you are dealing with aerodynamic models, or in general if your system is described by the so-called stiff equations[d].

It is clear that if you want your physics to behave consistently at different frame rates, you should find a way to separate the scene rendering and the physics simulation so that the physics integration time step is fixed or at least confined below a maximum value[e]. The maximum timestep allowed for your simulation can be calculated using math (interval arithmetic[f]) or by tuning your simulation at some ideal frame rate.

The best you can achieve on Unreal Engine is a variable time step below an upper bound (semi-fixed timestep[e]); it is called substepping. But first let’s have a look at all the physics settings available in Unreal Engine 4. If you want to jump directly to the details about Unreal Engine substepping, you can skip the following sections and read here.

Fixed Frame Rate

In Unreal Engine the physics time step has always some relationship with the rendering frame rate, so the first place to look at is: Project Settings > Engine > General Settings > Framerate. 

UE4 Fixed Delta Time

Here you can choose to set a fixed frame rate for your game. This means that the engine will always pass a fixed delta time to physics and tick functions. At the same time the engine will try to reach the desired frame rate. But what happens when there is a frame rate drop? In this case the actual frame rate will be slower than the fixed value but the delta time passed to physics will always be the same fixed value. This means that your simulation will run at a slower non-real-time speed. For example, if you set a fixed frame rate of 60fps but your game is running at 30fps because the machine is not powerful enough, then the simulation will run at half speed because in 33ms of real-time the game simulation will go only 16ms of fixed time forward.

Smooth Frame Rate

UE4 Frame Rate Smoothing

Frame rate smoothing is a way to cap the frame rate between a min and max value. It can be found here: Project Settings > Engine > General Settings > Framerate. It can be used to define the min/max acceptable frame rates. To better understand how Smooth Frame Rate works, an understanding of Vertical Sync is also needed as the two have a lot in common.  More info about it here.

Max Physics Delta Time

UE4 Max Delta Time

The engine settings about physics can be found here: Project Settings > Engine > Physics.

The Max Physics Delta Time property sets a maximum value for delta time during each physics iteration. This means that the physics time step is tied to the frame delta time until it doesn’t exceed the max physics delta time. When this happens, the physics time step remains fixed to this max value and the simulation starts slowing down thus becoming a non real-time simulation.

This can be useful if, for example, your game runs pretty stable at 60 fps and you know that your physics will work well above 50 fps. Then you can set a Max Physics Delta Time of 1/50sec and if you are ok with some occasional slowdowns in the simulation, you have done. But if your physics have to run at 60 fps and you want your game to run well at 30 fps, then you must use substepping.

Unreal Engine Substepping

The engine settings about substepping can be found here: Project Settings > Engine > Physics.

UE4 Substepping

Substepping is a technique used by Unreal Engine to ensure a certain degree of frame rate independency to the physics simulation. When the frame rate drops down, Unreal will put some extra physics iterations to ensure that the physics timestep will never exceed a maximum value. You can specify this upper bound  (Max Substep Delta Time) and a maximum number of physics substeps between two rendering frames (Max Substeps). Let’s say that you have set 16 ms as Max Substep Delta Time. This means that you don’t want the physics timestep to be greater than 16ms or, likewise, the physics frame rate to be smaller than 60fps. Now, if the rendering frame rate is 60 fps or above, there will be no substepping because the physics time step is lower than 16ms already. What happens when your frame rate drops below 60 fps? In this case the engine will put some extra physics substeps to ensure that the physics delta time doesn’t exceed 16 ms. So Unreal Engine will put 2 substeps of duration deltatime/2 when the fps are in the range from 30 to 60. When the rate drops below 30fps, 3 substeps of deltatime/3 will be executed. When the rate drops below 20fps, 4 substeps will be executed and so on.

The number of substeps encreases with the frame delta time until it reaches the Max Substeps value. Given the constraints of the Unreal Engine substepping, the max frame delta time allowed for a real-time simulation will be maxdt * maxsubsteps. Above this delta time the simulation will start slowing down becoming non real-time.

Let’s do some math. Let maxdt be the Max Substep Delta Time, maxsubsteps be the Max Substeps, currfps the current rendering fps, currdt=1/currfps the current frame delta time:

Target FPS = 1 / maxdt
This is the frame rate above wich there will be no substepping. It is the framerate that you should use to tune the game physics.

Limit FPS = 1 / (maxdt * maxsubsteps)
Below this frame rate there will be no more substeps and the simulation will start slowing down.

if currfps <= Limit FPS:
NSubsteps
= maxsubsteps

Substep DeltaTime = maxdt

if currfps > Limit FPS:
NSubsteps = ceil(currdt / maxdt)
Substep DeltaTime = currdt / NSubsteps

Here is some pseudo-code for the semi-fixed timestep:

The image below shows what happens when the frame deltatime is greater than maxdt * maxsubsteps (case B). In this case the sum of all the substep times is smaller than the actual deltatime and the simulation slows down.

Substepping timeline subdivision

Substepping Graph

Although the logic and the math behind the Unreal Engine substepping method are pretty simple, it can be still confusing to figure out the behaviour of the number and duration of substeps when the frame rate changes, given a certain configuration. I’ve come up with an interactive graph where you can play with different values and see how the substepping behaviour changes.


Unreal Engine 4 Substepping

As you can see in the above graph, the substep deltatime never goes above the max substep delta time but it can go a lot below it. This will guarantee that the game won’t explode (if we choose the right max deltatime) but can result in a computational overhead if we don’t pay attention to the values used. In particular, if the game is CPU bounded, the substepping mechanism could collapse and slow down the frame rate below the Limit FPS value. This because when the frame rate drops, the engine will put some extra substeps which will require more CPU cycles and, being your game CPU bounded, will slow down even more the frame rate. This chain effect will stop only when the frame rate will reach the Limit FPS value where no more substeps will be added.

The default values for the graph above show a possible configuration for a game tuned at a target physics frame rate of 40fps, and designed to run at an average speed of 60fps on high end machines and 30fps on low end ones. You can see from the graph that the physics will run at 60fps (16ms) both at 30fps and 60fps. Small frame rate fluctuations around these target rates won’t trigger any extra substep. Only when the rate slows down to 40fps we have 2 substeps at 80fps. In this way we can guarantee physics stability without any large CPU overhead.

Substep Tick Function

So you followed this article, activated the substepping and chose some suitable values for max substep deltatime and max substeps, but your game physics is still exploding and you didn’t see any substep influence when looking at your tick functions: they are still tied to the rendering frame rate and are still receiving the frame rendering deltatime. So where are these substeps?

The fact is that Unreal Engine substepping is running only under the hood and the tick functions in your actors and components are still being called at each rendering frame. This means that while the internal physics simulation is running smoother (collisions and motion integration), if your spring model is computed inside a tick function, it will gain no benefit from the substepping. In fact, if you compute the forces applied to a body every rendering frame and then the physics engine integrates those forces for N substeps at deltatime/N step intervals, the result is the same of integrating in a single step of deltatime duration. This because the forces are constant during each substep iteration.

To fix this problem you have to tell the engine to call some function in your code for each substep. There is a discussion in the Unreal Engine forum about substepping where Epic’s developers explain how to assign callbacks to be called for each substep tick[g].

Here I’m showing you a little code example of how to setup a substep callback in your project. The first thing to note is that you can access substepping only from an object that can have a rigid body, i.e. any Component extending UPrimitiveComponent. Here I’m subclassing an UStaticMeshComponent.

Here is the header code:

In the above code I’m overriding the main tick function wich will be called by the main rendering thread. I’m also defining a delegate OnCalculateCustomPhysics of type FCalculateCustomPhysics , a pointer to the rigid body and the SubstepTick function to be called during substepping.  Finally I’m defining some utility inline functions to get position, rotation, velocities directly from the rigid body. This because body transformations aren’t updated until the end of physics tick, so you have to read them from PhysX rigid bodies to get the updated values from the last substep.

Here are all the function definitions:

As you can see above, I’m binding the OnCalculateCustomPhysics  delegate to the SubstepTick function:
OnCalculateCustomPhysics.BindUObject(this, &UStaticMeshComponent::SubstepTick);

Then, for every main tick, inside the TickComponent function, you have to tell the BodyInstance to call the OnCalculateCustomPhysics  delegate (which will eventually call SubstepTick)
GetBodyInstance()->AddCustomPhysics(OnCalculateCustomPhysics);

In order to compile this code, you have to add “PhysX” and “APEX” to the PublicDependencyModuleNames array in yourgame.Build.cs module configuration file.

One big caveat when using substep callbacks is the fact that physics sub-stepping is running in a separate physics thread. This means that there are a lot of functions that you can’t call from a substep callback, because they cannot work under concurrency (many engine functions start with a check(MainThread) ).  So if you first designed your game without substepping callbacks and then you are trying to move all your physics code into substep callbacks in a late development stage, don’t expect the task to be easy; you’ll probably find that many things won’t just work under substepping, so be prepared to a lot of refactoring. (Since 4.18 Physics substepping runs in the main thread).

Post Physics Tick Function

Sometimes you need to adjust something just after the physics has been evaluated in order to be sure that what you are setting will go unchanged to the rendering phase.

If you set your primary tick to pre-physics, you need to register a secondary tick function for post-physics. You have to create a struct extending the struct FTickFunction , initialize it and then register it.

Here is the header code:

As you can see above, I’m adding a pointer to a MyComponent instance inside the struct FMySecondaryTickFunction . This pointer will be used inside the ExecuteTick callback to invoke a tick function inside MyComponent .

Here are the function definitions:

You can set a post-physics tick inside an Actor in a similar way as well.

By combining all these examples, you can easily setup a component listening to pre-physics, substeps and post-physics ticks.

Comparison with Unity 3D

unity-timestep

Unity physics timestep is very clean and simple. While Unreal Engine is using a semi-fixed timestep, Unity uses a fixed timestep instead. For each render frame, Unity executes a number of fixed physics timesteps (each one lasting exactly  a fixed timestep number of seconds) in order to consume the frame delta time:
NTimesteps = Math.floor(FrameDeltaTime / FixedTimestep)

Because the number of timesteps is an integer, there could be a remainder at each frame in the consumed delta time. This remainder is collected at each frame and added to the next frame delta time, eventually leading to the execution of an extra physics timestep when its value becomes greater or equal to FixedTimestep.

Here is some pseudo-code describing the fixed timestep:

The parameter Maximum Allowed Timestep sets a maximum value for the frame delta time (not for the timestep, which is fixed). This means that if the frame delta time is greater than this value, the physics will cap the delta time and the simulation will slow down. This is similar to what we have seen in Unreal Engine with Max Physics DeltaTime or with Max Substeps. Don’t confuse this with the Max Substep Delta Time property which is the equivalent of Unity’s Fixed Timestep. There is a bit of naming confusion here, so be careful.

Apart from the fixed vs semi-fixed model, one on the main difference between Unity and Unreal Engine is the fact that in Unity you have a simple and direct access to the physics tick through the FixedUpdate method of the Monobehaviour interface.

While the fixed timestep is the ideal model for game physics, it is not problem free. The main issue with fixed timestep is temporal aliasing caused by the accumulation of a remainder at each frame. When the remainder becomes equal or greater then the fixed timestep, an extra physics step will be executed, resulting in a little stuttering of the animation. This is more evident when the rendering framerate is not a multiple of fixedtimestep.

Another problem with fixed timestep, tied to the previous, is the fact that the main frame tick (the Update method of Monobehaviour) is often off synch with the physics tick (the FixedUpdate method of Monobehaviour). This is a well known problem for Unity developers which experience stuttering every time some object position computed in the Update is tied to another object position evaluted in a FixedUpdate. Fortunately simply moving the Update code into the FixedUpdate function will fix this problem. This is one of the problem that made Epic’s developers choose the semi-fixed timestep method for Unreal Engine; the fact that the physics timestep is not easily exposed in c++ and not at all in blueprint will make very difficult to cope with this issue in this engine[h] :

We actually had a debate about these two techniques [fixed and semi-fixed timestep] and eventually decided on semi-fixed, and here’s why:

If you use [fixed timestep] you have to use a timebank. If you want to tick physics at 60fps and you have a frame that took a little bit more than 1/60 you will need to have some left over time. Then you will tick the physics engine with the perfect 1/60 delta time, leaving the remainder for the next frame. The problem is that the rest of the engine still uses the original delta time. This means that things like blueprint will be given a delta time of 1/60 + a bit.

Example Project

I have put an example project on github here: https://github.com/gportelli/UEPhysicsExample.

Here is a video of the example running:

As you can see, there is a cube oscillating according to a damped spring model. You can change the physics parameters using the exposed editor properties. Using the default properties the oscillation will explode if you disable the substepping. The engine substepping is tuned to run at 60fps when the render frame rate is 30fps. When I disable the substepping in the video, you can see how the amplitude increases at each oscillation, eventually going to infinite. By enabling logging, you can see what is actually happening in the physics engine: a pre-physics tick, two substep ticks and a post-physics tick for each rendered frame.

References

Notes

  1. Numerical Analysis []
  2. Euler Method Numerical Stability []
  3. Spring Physics, Gaffer on Games []
  4. Stiff Equation []
  5. Fix your timestep! Gaffer on Games [] []
  6. Interval Arithmetic []
  7. Physics Sub-Stepping (substep callback) – Unreal Engine Forum []
  8. The reasons for semi-fixed time step – Unreal Engine Forum []

48 thoughts on “Everything you always wanted to know about Unreal Engine physics (but were afraid to ask)

  1. Varg

    Hi Giuseppe, very nice and useful article!

    Do functions such as SafeMoveUpdatedComponent(), MoveUpdatedComponent(), etc. would benefit from all of this? I have framerate/substepping problems in my project and I’m doing a massive use of those functions in my custom MovementComponent; I just couldn’t find a way to fix all the problems…

    Reply
    1. Giuseppe Post author

      The question is: are you running a physics simulation or a kinematic simulation? If you are using these functions in a MovementComponent, I guess you are working in kinematic and you have not enabled the “simulate physics” check for your actor, so you can’t use substepping. If you are not applying forces but you are just moving your actor frame by frame by applying a movement vector, you could manually fix your timestep at each tick with one of the methos explained here: http://gafferongames.com/game-physics/fix-your-timestep/
      Basically you can execute your movement updates several times for each tick if your deltatime is larger than a minimum value. You split the larger deltatime in smaller timesteps and update your actor position one timestep at a time.

      If you are running a physics simulation (the “simulate physics” check is enabled for your actor) and you want to add a substep callback to your MovementComponent, just register a substepping tick function using the UpdatedPrimitive->GetBodyInstance() to obtain the BodyInstance of your root UPrimitiveComponent (only UPrimitiveComponents like UStaticMeshComponent do have a rigid body). Follow the examples on my article to create the OnCalculateCustomPhysics delegate and passing it to the AddCustomPhysics at each TickComponent call:
      UpdatedPrimitive->GetBodyInstance()->AddCustomPhysics(OnCalculateCustomPhysics);
      Then in your TickSubstep custom function you can do your physics.

      Reply
      1. Varg

        Hi Giuseppe! I’m still having a hard time figuring this out.

        I don’t use physics at all, I just have a custom MovementComponent which derives from UPawnMovementComponent, and so it doesn’t have any kind of time-step management. I delved through the UE4’s UCharacterMovementComponent and saw that there is in fact some kind of time-step management (and there’s something called Iterations, too), but it’s not easy to reproduce this stuff into my custom MovementComponent due to the massive amount of things UE4’s UCharacterMovementComponent does into one single class.

        So, I got a few questions:

        1) I get that I have to implement this myself, and I wanted to implement Semi-Fixed TimeStep as showed into the post you linked (Gaffer on Games’ website). But where exactly do I need to do that? I guess I have to do it in the TickComponent function of my custom MovementComponent, is this right?

        2) in the TickComponent function of my custom MovementComponent, DeltaTime is passed; should I rely on that or should I calculate my own deltatime somehow?

        Thanks!

        Reply
        1. Giuseppe Post author

          1. yes, 2. yes
          But I’m not sure that you really need to implement a semifixed timestep inside your component. You say that you are not using physics. Are you simulating physics with any custom algorithm? What kind of frame rate problems do you have? What happens to your object when the frame rate drops?

          Reply
          1. Varg

            Thank you very much for taking the time to answer there! So, the question here is:

            Would you mind implementing time-step handling in a game which does not rely on physics that much, nor does it need multiplayer/networking?

        2. Giuseppe Post author

          Even if it relies on physics only a little bit, the frame rate fluctuations could be evident. So the answer is: make some tests on different machines and see what happens. If the behavior is ok, then do nothing. If your game is GPU intensive with lot of drops, or if at 30 fps the animations are very different from 60 fps and this has an impact on game mechanics, then implement timestep. You have two choices, implement it by yourself inside the engine Ticks; or enable physics and substepping on an actor and then update your custom physics when the TickSubstep is called on that actor using the deltatime received in that function (much easier).

          Reply
          1. Varg

            The game is GPU intensive; I didn’t notice any *relevant* frame drop to justify custom time-step handling but you know, you can never tell (the game is still in the middle of the development and this problem may show up any time). Also, I’m here to learn, so even if I won’t need time-step handling it’s a good thing to know how it works!

            I forced the game to 30 FPS and it still looks good and playable; at 12 or 10 FPS the game becomes very unstable, and at 5 FPS it goes completely bogus, but who would play a game at 10 or 5 FPS anyway?

            So, let me get this straight:

            1) when you say “implement it by yourself inside the engine Ticks”, do you actually mean the engine tick code handling? Or a TickComponent function inside my custom UPawnMovementComponent would just do?

            2) about the other option you propose (enabling physics), are you suggesting to enable physics on an actor just to catch the TickSubstep (so to make advantage of UE4’s substepping) and use its deltatime to make my pawn move/jump/fall, etc.? Is this right?

        1. Varg

          2. is a very nasty (and clever) trick! Can’t wait to try it out. Thank you very much for your help and keep up the good work!

          Reply
        2. Varg

          Just out of curiosity, if I want to implement time-step inside of a TickComponent or Tick function, how should I go to do something like:

          float remainder = 0;
          double currentTime = time();

          while(true)
          {
          double newTime = time();

          double frameTime = newTime – currentTime;

          […]

          }

          I tried to get the currentTime as first thing in the Tick, then in the while loop I get newTime, but (obviously) doing frameTime = newTime – currentTime returns 0…so everything stops there…

          Reply
        3. Giuseppe Post author

          Reply
  2. Andrew

    Great post! It’s a little confusing switching back and forth between FPS and delta time but otherwise your explanations are very clear. It’s a shame that’s it’s not easier to expose the callbacks in c++ and that it’s impossible in blueprint. Substepping without callbacks seems pretty useless for any simulation driven by non-uniform forces.

    Reply
    1. Giuseppe Post author

      Hi, I understand the difficulty in thinking fps-wise versus deltatime-wise; also, depending on context, sometimes I’m most comfortable with fps or deltatime, that’s why I’ve come up with a graph based both on fps and deltatime.
      As for the blueprint callbacks, I’m not sure if it is impossible at all. If you want to make some tests, you should define some BlueprintImplementableEvent (let’s call it BlueprintSubstepEvent) to dispatch from c++ at each substep. Here the only problem could be the fact that the substepping is not running in the main thread, and this could be a problem when calling blueprint functions and events. If this method works, than you can create a more generic event system using Dynamic Multicast Delegates to bind to an event of a blueprintclass from another blueprint class. This is the best you can achieve in blueprint.

      Reply
  3. Jarbles Westlington

    hey thanks a lot for the great article, helped me understand the weirdness of UE4 a bit more. You probably wont see this, but I’m trying to get my character movement component (no physics enabled of course) to conform to substepping. Most of my character is modeled through blueprint, so I was hoping to find any way to do this through blueprint. This is a shot in the dark but I’ve been at a wall with my project for a while and am at a loss for what to do.

    Reply
    1. Giuseppe Post author

      If you are not using physics, you should implement a substepping algorithm on your own. You can do it in code or blueprint as well. You can find a lot of discussion about manual substepping in the comments. Basically you can perform multiple physics calculation steps instead of one only when the Deltaseconds exceeds some desired max value.

      Reply
    1. Giuseppe Post author

      Yes, it has been fixed. I’ve just updated the section about Fixed Frame Rate. I’ve also upgrated the example project to UE4.15

      Reply
  4. Rob Baker

    “But what happens when there is a frame rate drop? In this case the actual frame rate will be slower than the fixed value but the delta time passed to physics will always be the same fixed value. This means that your simulation will run at a slower non-real-time speed. For example, if you set a fixed frame rate of 60fps but your game is running at 30fps because the machine is not powerful enough, then the simulation will run at half speed because in 33ms of real-time the game simulation will go only 16ms of fixed time forward.”

    Are you sure? Examining the engine code the only effect using a fixed frame rate has is to cap the maximum frame rate by having the engine sleep if it could have executed a faster rate. This shouldn’t affect physics at all.

    Reply
    1. Giuseppe Post author

      Yes, I’am. I’ve just checked on UE 4.25.

      The engine code computes a wait time for the current frame. If this wait time is positive (meaning that the actual frame rate is greater than the fixed one) it simply waits; but if it is negative, the game physics slows down becoming non real time.

      This is very easy to test. Just set a fixed frame rate to a value which is two times your maximum frame rate on your machine and watch your game slowing down to half speed.

      The code fragment in the engine source code (UE4.25.1) is in UnrealEngine.cpp:2112 inside the function UEngine::UpdateTimeAndHandleMaxTickRate()

      Reply
      1. Rob Baker

        Wow, that’s quite shocking that Epic would allow such a major fail to be exposed like that. I can’t imagine what their rationale was. Apologies for questioning you on this.

        Reply
  5. Rob Baker

    “Frame rate smoothing is a way to cap the frame rate between a min and max value. It can be found here: Project Settings > Engine > General Settings > Framerate. This feature is meaningful when combined with hardware vsync.”

    Having vsync enabled or not matters little here. The engine will perform frame time smoothing regardless of whether vsync is on or off. To say it only becomes meaningful when it’s on is misleading.

    Reply
    1. Giuseppe Post author

      Thanks for your comment, I’ve updated the paragraph and also added a link to the new official documentation for the smooth frame rate option.

      Reply
  6. kelton

    Just wanted to say thank you so much for this write up! Love all the examples + intractable graphs. I am a student working on lots of physics stuff in unreal and this is fascinating to me. I didnt know substepping was a thing before I read this. One of the most well together put info info pages ive ever seen.

    Reply
    1. Giuseppe Post author

      I think that Unity solution is more elegant and straightforward. But each solution has pros and cons. Unity solution, for example, causes stuttering when the rendering framerate is not a multiple of fixedtimestep

      “The main issue with fixed timestep is temporal aliasing caused by the accumulation of a remainder at each frame. When the remainder becomes equal or greater then the fixed timestep, an extra physics step will be executed, resulting in a little stuttering of the animation.”

      Reply
      1. Pandanym

        I’ve been using Unity for a while now, and with interpolation enabled on your rigidbodies, there is no stuttering. In my opinion, Unity’s solution is way better for devs, especially since you can’t use the substeps inside blueprints in UE.

        Reply
  7. Anthony

    Thank you for this incredible resource. As someone trying to get a handle on UE4 after coming from Unity this was very informative.

    Now, I understand this is for physics. But what if I wanted game logic to also operate using substepping? I suppose I should modify the UE4 source code to achieve this huh?

    Basically to get game logic (movement calculations, interactions, etc) to be deterministic or ‘semi-deterministic’ as I like to say with a fixed tick-rate, I’d have to try to shift Actor behavior to only update/tick during the substeps so that it is decoupled from rendering. This seems much more trickier in Unreal than it is in Unity, but on the flip side, source access makes this very approachable and flexible to tackle however I want.

    Reply
    1. Giuseppe Post author

      If you need to do some physics logic, you have to add it on a substep, cause it needs to interact with the forces and torques added on each physics substep.

      If you need to do some other kind of logic in a fixed timestep way, you can implement a simple fixed timestep algorithm in your tick. There is a good example in the engine class for spring arm: USpringArmComponent::UpdateDesiredArmLocation()

      Here you can see that when bUseCameraLagSubstepping is true, the internal logic is executed n times dividing the current deltatime in fixed timesteps and accumulating a remainder. Note that this is not a semi fixed timestep but an actual fixed timestep implementation.

      Reply
      1. Anthony Barranco

        yes indeed, I thought about making an actor that manually ticks other actors like this. I’m still brushing up on Unreal engine but I suppose I would need to make sure the “master simulation” actor is aware of all other actors in a given scene/level and then do custom ticks on them using this loop. This is kind of how I would do it with Unity but in a more explicit way with a top level Monobehaviour (aka actor). Tricky gotchas like how the movement component updates after actors tick may be the problem with this solution since those components would also need to tick in these loops per substep to get accurate calculations

        Reply
  8. Ben

    So I’m confused – I looked at the Unreal Documentation now (approved for 4.26) and it clearly says the physics sub-stepping is on a separate thread (https://docs.unrealengine.com/4.26/en-US/InteractiveExperiences/Physics/Substepping/). I don’t understand why EG can’t get on top of physics time-stepping… even their own tutorial on asynchronous physics (https://docs.unrealengine.com/5.0/en-US/PhysicsFeatures/AsyncPhysics/) suggest that activating this would make the project deterministic… but I just don’t understand (given all the issues on sub-stepping) that this could possibly be true. I understand the philosophical view from a gaming perspective (games don’t need to be deterministic) – but there’s a lot of applications that would really benefit from a fixed time-step (but I guess that argument was lost a long time ago).

    Reply
    1. Giuseppe Post author

      I think the 4.26 documentation is outdated about the substepping on separate thread, but I’m not exactly sure when they moved the substeps to the game thread.

      As for the UE5 docs, the async physics is a step closer to real determinism than substepping. Here the physics runs at fixed timesteps instead of substepping which guarantees only timesteps smaller that a max value. Perfect determinism, however, is difficult to achieve here given the real time nature of the engine. Things that can ruin determinism are the sync with the game thread when the input forces are fed to the physics thread and the fact that physics tick duration may exceed the timestep. Also when you dive into the determinism rabbit hole, you may consider aspects down to the level of ieee floating point implementation on different hardware: how diffferent architectures deal with loss of precision with floating point operations.

      I understand the need for determinism in applications outside the game context. I think the way to go is to modify the engine in a way that removes the real time constraint from its physics simulation. It could be as simple as running everything on a single thread with a fixed timestep regardeless of the actual frame time. This means non real time simulation (it can go faster or slower than real time depending on the simulation complexity and the machine). I’ve not checked if there is already a setting in UE for this but it is certainly an easy modification to have fixed deltaseconds.

      Reply
  9. Rigel

    I can’t seem to get my actor to execute more than 1 substep tick per render tick. I have the AddCustomPhysics call in the Tick() method (BeginPlay, as shown in the example above, did not work), and bound in the constructor. Playing around with the substep settings doesnt change anything.

    The only difference between my example and yours is I have my movement code in the actor itself. I am expecting the substep function to call multiple times under low frame rates, but that isn’t happening.

    I appreciate any help, been banging my head against a wall for a few days trying to get reasonable consistency at lower framerates and good collision, and this blog post helped a lot in my understanding in what needs to be done to fix it.. My Code:

    ADrifter::ADrifter()
    {
    …..
    OnCalculateCustomPhysics.BindUObject(this, &ADrifter::SubstepTick);
    }

    void ADrifter::Tick(float DeltaTime)
    {
    Super::Tick(DeltaTime);
    Logger::Info(TEXT(“Tick! %f”), DeltaTime);

    DrifterRoot->GetBodyInstance()->AddCustomPhysics(OnCalculateCustomPhysics);

    ….
    }

    void ADrifter::SubstepTick(float DeltaTime, FBodyInstance* BodyInstance)
    {
    Logger::Info(TEXT(” SubstepTick! %f”), DeltaTime);
    }

    Output @ MaxFPS=10

    LogTemp: Display: Tick! 0.100000
    LogTemp: Display: SubstepTick! 0.100000
    LogTemp: Display: Tick! 0.100000
    LogTemp: Display: SubstepTick! 0.100000
    LogTemp: Display: Tick! 0.100000
    LogTemp: Display: SubstepTick! 0.100000

    Reply
    1. Giuseppe Post author

      Hi, check if your root component is a subclass of UPrimitiveComponent (like a StaticMeshComponent for example), and make sure to enable physics on it using SetSimulatePhysics(true) or via a check in the editor.

      Reply
      1. Rigel

        I have a USphereComponent as a root, which derives from UPrimitiveComponent, as my root component, and do have simulate physics set. Weird.

        I have a pretty complex actor. There is a SphereComponent at root, with a UStaticMeshComponent attached to that, and then attached to that is numerous other classes derived from UStaticMeshComponent called UParts (user created space ships like Kerbal Space Program). Any idea if this could be causing issues? Simulating physics in general seems a bit buggy with this actor, so maybe I’ll just try out a simpler actor to see whats going wrong.

        Reply
        1. Giuseppe Post author

          I think the problem is that you are calling the AddCustomPhysics() from the actor Tick(). You have to call it from an ActorComponent. For this reason in my code base I have created a PhysicsComponent extending UActorComponent. I add this component to the actor I want to substep and in its TickComponent I call the AddCustomPhysics() on the root component of the actor.

          void UMyPhysicsComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
          {
          Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

          UPrimitiveComponent* Root = Cast(GetOwner()->GetRootComponent());

          Root->GetBodyInstance()->AddCustomPhysics(OnCalculateCustomPhysics);
          }

          Reply
  10. John Adam Daniels

    You are very smart! Thank you for the great article.

    I am working on a physics base 3D motorcycle game and Jittery Physics from Frame Drops was wiping the floor with me.
    This article put me into the right direction.

    If it helps anyone else I set mine up as the following for silky smooth physics :)!

    Engine 4.27
    Engine fixed frame rate = 60 (FPS)
    Physics Max Substep Delta Time = 0.00833 (120 FPS)
    Max Substeps = 4
    Async checked

    Thank you again, really appreciate all the hard work you put into this article.

    Reply
    1. Giuseppe Post author

      I’m glad to be helpful. Notice that 120 fps can be pretty demanding, especially if you have a complex model and many vehicles. I was able to run smoothly with a bit more than 50. Notice also that my article is missing an important advice to help keeping your simulation stable: when applying friction forces, never allow them to change the orientation of the input velocities. In other words: friction can at most stop you, but never reverse your speed. In this case, due to undersampling, friction forces are injecting energy into the system instead of just draining kinetic energy. The rule is, when a velocity vector is used to compute a friction force, the effect of that force for a frame on the component of velocity parallel to the force, must be at most of cancelling the velocity, never changing its sign. Use this rule to cap friction forces.
      Hope it can help.

      Reply
  11. Phillip Zanet

    Howdy Giuseppe,

    I have a situation that I’m not sure if it will benefit from this or not, so I implore your expertise on the topic.
    I have a trace running on tick that checks each render frame if something is being hit.
    Obviously at 10 or less frames, we’re skipping traces.
    I had been looking into substepping to try to get the parts that are missed. For more info, it’s tied to animation. Imagine you swing a sword. at 120 fps, no prob, all frames are done. at 5 or 10, most don’t show up and the traces fail.
    So my question is:
    Would it benefit from tying it to the AsyncPhysicsTick and use substepping to compute the physical location of the trace source somehow?
    Currently, I just tied my logic on the AsyncPhysicsTick however the behaviour is identical as with tick. I’m thinking I’d need to use the callback method but I’m severely doubtful it would work.
    Much appreciated article and have a pleasant day!

    Reply

Leave a Reply to Giuseppe Cancel reply

Your email address will not be published. Required fields are marked *