Physics Tick / Unity Fixed Update

Hi - I’m trying to port a foiling boat simulation I wrote in Unity into Unreal. In Unity there is the Update and FixedUpdate calls. Because I’m using PID controllers I want to be able to do the euivalent of FixedUpdate and call some of the routings every 100th of a second (0.01 secs) regardless of screen update frame rate. I think this is what the AsyncPhysicsTIck is for but I can’t seem to figure out how to correctly implement it in C++. Can anyone help with this? Thanks.

1 Like

Once async physics tick is enabled, use the following override in your actor:

virtual void AsyncPhysicsTickActor(float DeltaTime, float SimTime) override;

Should work just like the Tick override, but it’s asynchronous. Keep in mind some physics functions might only work correctly on GameThread.

Thanks for the reply Screwdriver. Would you mind providing a bit more detail on how to implement this. I’m still pretty new to Unreal and am moving slowly from C# to C++! Cheers.

In your actor’s header file, add the function like so:

UCLASS()
class MYGAME_API AMyActor: public AActor
{
    GENERATED_BODY()

public:

    virtual void AsyncPhysicsTickActor(float DeltaTime, float SimTime) override;

And then declare the function in your .cpp file:

void AMyActor::AsyncPhysicsTickActor(float DeltaTime, float SimTime)
{
    // This runs on every async tick, with the length specified in the settings.

    ...

I still seem to be getting a DeltaTIme and SimTime that is tied to my set project frame rate.

I call it like this in my actor:

void ABoatMaster::AsyncPhysicsTickActor(float DeltaTime, float SimTime)
{

// Super::Tick(DeltaTime);
float FixedTimeStep = SimTime;

// Update the boat data
UpdateBoatData(FixedTimeStep);

Then in Project settings I can set a fixed frame rate of whatever I want and edit the Physics frame rate thus?

I feel that I’m setting it up wrong. I also get the whole thing running in super slowmo when I turn Tick Physics Async. I’m obviously missing something pretty basic.

Actually I see now its not rebuilding. It gives the errors:

Severity Code Description Project File Line Suppression State
Error LNK1120 1 unresolved externals Malolo_Hero D:\Epic Stuff\Malolo_Hero\Binaries\Win64\UnrealEditor-Malolo_Hero.dll 1
Error LNK2001 unresolved external symbol public: virtual void __cdecl ABoatMaster::Tick(float) (?Tick@ABoatMaster@@UEAAXM@Z) Malolo_Hero D:\Epic Stuff\Malolo_Hero\Intermediate\ProjectFiles\BoatMaster.gen.cpp.obj 1
Error LNK2001 unresolved external symbol public: virtual void __cdecl ABoatMaster::Tick(float) (?Tick@ABoatMaster@@UEAAXM@Z) Malolo_Hero D:\Epic Stuff\Malolo_Hero\Intermediate\ProjectFiles\BoatMaster.cpp.obj 1

I have it in my BoatMaster.h as:

include “CoreMinimal.h”
include “GameFramework/Pawn.h”
include “PID_ROC.h”
include “WaterDataBase.h”
include “WaterBodyLakeActor.h”
include “WaterBodyLakeComponent.h”
include “BuoyancyComponent.h”
include “WaterBodyActor.h”
include “WaterDataUnrealWater.h”
include “BoatMaster.generated.h”

UCLASS()
class MALOLO_HERO_API ABoatMaster : public APawn
{
GENERATED_BODY()

public:
ABoatMaster();

virtual void AsyncPhysicsTickActor(float DeltaTime, float SimTime) override;

If you have Tick declared in your header file, you must also create the function in your cpp file. If you don’t, you’ll get the linker error shown above.

Also, try using DeltaTime rather than SimTime, although I’m not particularly sure myself what the difference is.

Thanks for getting back to me. I think I was creating it in my .cpp file. I have the following:

void ABoatMaster::AsyncPhysicsTickActor(float DeltaTime, float SimTime)
{

float FixedTimeStep = SimTime;
UpdateBoatData(FixedTimeStep);

Am I misunderstanding what you mean by creating the function? Sorry to be a little fuzzy on this!

So, the compilation error you’re getting seems to be because you’ve defined an ABoatMaster::Tick(float DeltaTime) somewhere in your code. If you have, go ahead and remove it, and you should be able to compile.

As for making the other function, AsyncPhysicsTickActor, what you’ve posted seems correct.

I have in my header -

public:
ABoatMaster();

virtual void AsyncPhysicsTickActor(float DeltaTime, float SimTime) override;

In ABoatMaster.cpp I have -

ABoatMaster::ABoatMaster()
Which sets defaults values

and

void ABoatMaster::BeginPlay()

then

void ABoatMaster::AsyncPhysicsTickActor(float DeltaTime, float SimTime)

That’s all I can find. But I still get that same linking error.

Does the void ABoatMaster::BeginPlay() cause an issue?

Or perhaps I’m missing a header file I should be including?

Oh - this was hanging around at the bottom of my header!

public:
/virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

Hmmm… now it compiles but just doesn’t execute that routine. I’ve turned on Async Physics Tick Enabled. I assume there’s probably something obvious that I’m not doing? Thanks again for helping with this. It’s so easy on Unity, so I’m not sure why it’s so buried in Unreal.

Add the following line to your constructor and try again:

bAsyncPhysicsTickEnabled = true;

Still nothing. I’ve checked Async is turned on everywhere…

you can kind of simulate a Unity->FixedUpdate()
by using standard Tick() but then giving it a defined Tick interval through
PrimaryActorTick.TickInterval = [FloatValue];

this will still hitch if the there is a hitch in the current Game loop but by spacing the interval the hitches shouldn’t be too often, and you can still lock to a designated region of the game loop

  • Engine receives input
  • inputs sent to bound consumers
  • pre-Physics (Default setting)
  • Phsysics
  • Post-Physics
  • Render

for the equivelent to Uinty->PhysicsTick() this would probably be similar to setting TickGroup = ETickingGroup::TG_PostPhysics though lockstep to frame is supposed to be the default behavior.

other then having things happen in different Tick Groups be aware that everything in a given TickGroup must complete before the next step of the GameLoop can continue.

Please be aware that Unreal enforces full thread safety so State variables in Async functions should be considered inaccessible to prevent race conditions.