Last Updated on 17/05/2024
Unreal has Async Physic Tick which helps you to simulate physics with consistent framerate. This is great for replicating physics simulations and for better and accurate physics. Let’s see how you can implement and use Async Tick properly.
Setting it Up
Actor Component & Scene Component
Async Physic Tick is in Actor Component, Scene Component inherints from it so you can use same thing in both.
Found here (ActorComponent.h):
You can do this:
public:
virtual void AsyncPhysicsTickComponent(float DeltaTime, float SimTime) override;
void UMySceneComponent::AsyncPhysicsTickComponent(float DeltaTime, float SimTime)
{
PhysicsTickWorker(DeltaTime); //Function where you keep all your physics tasks
Super::AsyncPhysicsTickComponent(DeltaTime, SimTime); //Add this if you want it to work in Blueprints, this should be at the bottom, after your c++ code
ReceiveAsyncPhysicsTick(DeltaTime, SimTime); //This might get execute in Super, i ran my code without it and it was fine
}
You need to enable Async Tick in constructor, theres this thing but it’s in private:
It goes here:
You can use this function:
I used it in construction and it was fine.
UMySceneComponent::UMySceneComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
SetAsyncPhysicsTickEnabled(true);
}
Just don’t put SetAsyncPhysicsTickEnabled in begin play:
It wont trigger in multiplayer, if it doesn’t have owner.
Actor
Almost same thing in Actor:
public:
virtual void AsyncPhysicsTickActor(float DeltaTime, float SimTime) override;
void AMyActor::AsyncPhysicsTickActor(float DeltaTime, float SimTime)
{
PhysicsTickWorker(DeltaTime);
Super::AsyncPhysicsTickActor(DeltaTime, SimTime);
ReceiveAsyncPhysicsTick(DeltaTime, SimTime);
}
Constructor:
AMyActor::AMyActor()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.TickGroup = TG_PrePhysics;
bAsyncPhysicsTickEnabled = true; //You can access this in here
}
In Actor bAsyncPhysicsTickEnabled is little different:
In actor blueprint it’s this thing:
Enable it in here:
Now we just need to tinker with Async Tick Settings in Edit -> Project Settings.
Enable Tick Physics Async and set the time step.
You can calculate delta time like this (in the box), 1 / 120 which means 120 frames or ticks in second.
AddForce
AddForce applies Delta Time from the main thread so using this in Async tick is the worst thing you can do.
AddImpulse
AddImpulse is what you want to use in Async tick. You need to apply Delta Time of async tick into your force calculation before adding it into AddImpulse.
Remember that now you are applying acceleration.
So something like this, will work correctly:
Some of the functions only work in main thread, like get component location or rotation, this can result in stuttering because values are updated in other tick. It’s best to build your own functions which gets the values from the physics rigidbody, in otherwords, you actually need to do this entirely in C++.
More to come!
I’ll keep updating this as i research this feature a bit more.