In Unreal Engine 5.4.4, I see the following options under Project Settings > Engine > Physics > Framerate:
Substepping: Enables physics sub-stepping. This feature is still experimental, and some functionality may not work correctly.
Substepping Async: Enables sub-stepping for async physics simulation. This feature is also experimental and may have limited functionality.
Tick Physics Async: Runs the physics simulation on an async thread. This feature is experimental, and certain features may not work as expected.
Async Fixed Time Step Size: Defines the time step size for async physics simulation. This setting only applies when async physics is enabled.
Max Substep Delta Time (only available if Substepping is enabled): Specifies the maximum delta time (in seconds) for an individual physics substep.
Max Substeps (only available if Substepping is enabled): Sets the maximum number of substeps allowed per physics update.
From Unreal Docs Physics Sub-Stepping I can see that Substepping, Substepping Async, Max Substep Delta Time and Max Substeps are all related to sub-stepping.
If I enable Tick Physics Async, do the other options, aside from Async Fixed Time Step Size, still have any effect?
Shouldn’t Tick Physics Async and Substepping be mutually exclusive?
Reading the thread you mentioned, I’m surprised to learn that UActorComponent::AsyncPhysicsTickComponent runs on the Game Thread. I was assuming it was called on one of the Physics Threads. But, if I understood correctly, it will be executed once by physics tick anyways and it’s not tied in any way to the Game Thread tick rate, right?
Now, at the code that goes in UActorComponent::AsyncPhysicsTickComponent, instead of obtaining physics state and adding forces and torques through the FBodyInstance returned by UPrimitiveComponent::GetBodyInstance, I’m doing all those things through the FBodyInstanceAsyncPhysicsTickHandle returned by UPrimitiveComponent::GetBodyInstanceAsyncPhysicsTickHandle. That’s the correct thing to do, right?
When I get the physics state from the FBodyInstanceAsyncPhysicsTickHandle, am I obtaining the (potentially stale) physics state from the Game Thread or the latest state from the Physics world?
Also, are there plans to make the API of FBodyInstanceAsyncPhysicsTickHandle equivalant to the API of FBodyInstance? I miss convenient methods like the AddForceAtPosition and the self-descriptive names of methods from FBodyInstance (In example, FBodyInstance::GetUnrealWorldVelocity() instead of FBodyInstanceAsyncPhysicsTickHandle::V()).
[…] it will be executed once by physics tick anyways and it’s not tied in any way to the Game Thread tick rate, right?
Yes, that is correct. (Well kind of, as it is still kicked off by the main GameThread tick, same as the solver tasks, but they are not 1 to 1).
When I get the physics state from the FBodyInstanceAsyncPhysicsTickHandle, am I obtaining the (potentially stale) physics state from the Game Thread or the latest state from the Physics world?
That handle gives you access to the physics thread state of that object (not the game thread state).
That said, using Game Thread state is not necessarily bad. It is the state the rest of the game/engine code sees and uses. Therefore that is the state to use if you are working with other game data (in fact, in these cases you probably don’t need to use the async physics tick either, just the normal tick).
I’m doing all those things through the FBodyInstanceAsyncPhysicsTickHandle returned by UPrimitiveComponent::GetBodyInstanceAsyncPhysicsTickHandle. That’s the correct thing to do, right?
Also, are there plans to make the API of FBodyInstanceAsyncPhysicsTickHandle equivalant to the API of FBodyInstance?
I am not the author of that handle, so let me check with the team and get back to you to see if there is something more appropriate in UE 5.4 which is the version you are working on.
What is your use for the Async Physics tick? Based on that I will be able to provide a better answer (as it depends on what data you need access to and what you need to do exactly).
If you need to do work at the physics step level, the current recommended way to do it is by implementing your own sim callback.
The Async Physics Tick has a non-trivial performance impact.
See TSimCallbackObject.
Sadly we don’t have a tutorial or in depth documentation about them yet, but there are some code examples in engine, as they are used by a few systems (the async physics tick being one of them).
If you don’t need to do work at the physics step level, then you don’t need to use the Async Physics Tick (even when async physics is enabled).
That said, using Game Thread state is not necessarily bad. It is the state the rest of the game/engine code sees and uses. Therefore that is the state to use if you are working with other game data (in fact, in these cases you probably don’t need to use the async physics tick either, just the normal tick).
Thanks for pointing that out. That aligns with my understanding. I use the Game Thread state whenever displaying information on the HUD or driving sound and animation parameters.
What is your use for the Async Physics tick?
I’m developing a flight simulator. Every physics tick, I retrieve the current state of the physics particle representing the aircraft, calculate the aerodynamic forces and torques, and apply them. Doing this on the game thread tick introduces instabilities in the calculations.
If you need to do work at the physics step level, the current recommended way to do it is by implementing your own sim callback. The Async Physics Tick has a non-trivial performance impact.
Would implementing a custom simulation callback be beneficial for my use case? I’m unsure what advantages that would have compared to using async physics ticks. The lack of documentation also makes it an obscure option when compared to the simplicity of async physics ticks.