Download

Ticking actor threading issue. Setting variable gets overwritten at times.

With a world tick start function defined as: OnWorldTickStart(ELevelTick TickType, float DeltaTime) we set two variables (Time based on DeltaTime) in this function. It seems to be that this is a multi-threaded call which at times results in a slight shift back in time as the first call sets it, second sets it based on a slightly older time which results in a negative time shift, not good.

Any thoughts are greatly appreciated as proper timing is critical in my project!

If I understand correctly, both functions are firing at once rather than OnWorldTickStart always firing first.

BeginPlay will run before Tick does, but if it’s not possible to put code in there, there is another option.

In your tick function, have a variable that essentially disables the first tick. Thus, even if the two functions run at once, the tick function will not start it’s code until the next frame.

Ex:



Tick(){
    if(!FirstTickHappened){
       FirstTickHappened = true;
       return;
    }

    //Rest of tick code
}


Thanks for the feedback! I am still learning all that UE4 has to offer and I may have not explained it well. Does this explain better as to what I am doing? (Excluded other code for clarity. If there’s something I missed that would help let me know I can add it in.)

In MyGame.h:


protected:
void OnWorldTickStart(ELevelTick TickType, float DeltaTime);

In MyGame.cpp:


Init(){
    FWorldDelegates::OnWorldTickStart.AddUObject(this, &UMyGameGameInstance::OnWorldTickStart);
}

void UMyGameGameInstance::OnWorldTickStart(ELevelTick TickType, float DeltaTime)
{
    float a = someOtherClass::getFloata();
    //Do some math with DeltaTime
    a = DeltaTime + a;
    someOtherClass::setFloata(a);
    return;
}

This is very simplified version of the code, but effectively the same thing. The variable a should always increase but doesn’t almost as if OnWorldTickStart() fired in two different threads and one of the most recent sets a first. Then the last one sets a again causing a step back in time.

Few interesting things happening here.

First, you could try something like this:



#include "EngineGlobals.h"
...
//In your function
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, "OnWorldTick");


To see if it actually IS running twice.

Second, there are multiple worlds. For example, the editor is a world, while in game is a world. It’s possible both worlds (while completely separate) start ticking at the same time and so you’re getting the event called from both.

Third, delta time is a fluctuating number that is based on the current framerate. It’s possible the game isn’t fully instantiated when this function is called and thus the deltatime isn’t properly set at that point. Also possible that the above is happening, and the other world has a different delta time passed in.

Is what you are trying to accomplish not possible using begin play? Or perhaps the first tick with the deltatime from within the Tick function?