Tick not being called on client version of pawn

I’m working on adding multiplayer to my game of rolling balls. I need to run some code on the client every tick, but the Tick() function appears to never run on the client.

void ABallPawn::Tick(float DeltaTime) {
    Super::Tick(DeltaTime);

    if (IsLocallyControlled()) {
        UE_LOG(LogTemp, Warning, TEXT("TICK LOCAL"));
    } else {
        UE_LOG(LogTemp, Warning, TEXT("TICK NON-LOCAL"));
    }
}

“TICK NON-LOCAL” is spammed in the console, but “TICK LOCAL” is never logged. Please help.

edit:
Anyone have any ideas why this is happening? I’ve also tried several alternatives to IsLocallyControlled(), none of which have worked. It appears that my Actor is simply not ticking on the client when in multiplayer.

Hey shoffing,

Have you tried:

void ABallPawn::Tick(float DeltaTime)
{
	if (Role < ROLE_Authority)
	{
		UE_LOG( LogTemp, Warning, TEXT("CLIENT") );
	}
	else
	{
		UE_LOG( LogTemp, Warning, TEXT("SERVER") );
	}

	Super::Tick( DeltaTime );
}

I just tried this, and unfortunately it did not work. My output log looks like

...
LogTemp:Warning: SERVER
LogTemp:Warning: SERVER
LogTemp:Warning: SERVER
LogTemp:Warning: SERVER
LogTemp:Warning: SERVER
...

and “CLIENT” is never logged.

That means the current window / user you’re running is the current authoritative role.

Try running a dedicated server or by running more than one client, you should see the log, “CLIENT”.

I am running with more than one client in the editor, using the dropdown next to the play button. Are there separate output logs for each instance of the game (server log, client1 log, cilent2 log, etc)? I’m only seeing the one output log in the editor, and I just assumed that all outputs were piped to that. If that’s not the case, it would definitely explain this.

I have the Output Window open, which can be opened if you go to Windows → Developer Tools → Output Log.

I have this code in my Character class:

void ASocketTestingCharacter::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

	if( Role == ROLE_Authority )
	{
		UE_LOG( LogTemp, Warning, TEXT( "SERVER" ) );
	}
	else
	{
		UE_LOG( LogTemp, Warning, TEXT( "CLIENT" ) );
	}
}

I have this set for number of players:

98550-449537_00.png

When I press Play, in the editor. This is what I see in the Output Log.

98561-449537_01.png

One of the windows is the server (Role == ROLE_Authority), meaning it has control over the client → server model. The other window is the client, meaning it doesn’t have control of the client-> server model ( Role != ROLE_Authority ) or ( Role < ROLE_Authority ).

I am not sure what is causing your issue but everything appears to be working on my end.

Hello,

I’m answering here to inform this problem or bug is not solved at all, it also touches UMod too after I upgraded from 4.10.2 to 4.12.5. Before the upgrade no problems, Tick was called both client and server.
With the update, any Tick method client side is ignored except the custom player controller if any is defined.
I tested this in UMod, hooking only 1 Tick function in the Character C++ derived class and the print worked fine server side but didn’t print in client console. I tried deriving Tick function only in my custom player controller and that worked both client and server. When all Tick methods are hooked then still only the player controller’s Tick is called client side.

Even BP entities do not get any Tick method called client side. I didn’t try hooking Tick in player controller BP as my project is majority C++…
I even commented my network hooking code in C++ to check if that was the problem but nothing changed.
I enabled actor Tick using SetActorTickEnabled(true) and PrimaryActorTick.bCanEverTick = true on the contructor of each replicated tick enabled entities.

I had similar issue.

In my case the tick didn’t get called at all. To solve this, I had to add a ‘Tick’ node in bp. It didn’t have to have any logic but it had to be in bp graph in order to make Tick in code be called. Dunno if it’ll help you in your case, but it would be worth trying.

Ok sp after a long research I know what exactly causes Tick to not work client side : the key is BeginPlay.

Upgrading from 4.10 to 4.12 changes the way actors registers ticks instead of registering in PostInitProperties it’s registered in BeginPlay which is a terrible bad thing as Epic Games makes abstraction of the bug that BeginPlay is not called client side.

To go further I identified the line which breaks it’s a simple if condition inside PostNetInit. The PostNetInit is actualy called correctly however the condition at line 2924 in Actor.cpp is failing. The problem is not MyWorld being NULL but it’s MyWorld->HasBegunPlay that returns always false when the function is called. Now if you move to World.cpp you will identify the function HasBegunPlay and identify the third part of the condition which is the problem ! It wants bBegunPlay to be true however bBegunPlay is true only when all BeginPlay has been called so to have BeginPlay called client side you need to have it already called !! This makes just no sense, I don’t know what you guys at Epic wanted to do but that is realy weird condition…

1 Like

In my case that was caused after calling RestartPlayer to switch player from Spectator to Player state. The reason was that PlayerState->bOnlysSectate not set to false, so player pawn was not initialized and it’s input not set up.

Hello,

I managed to get it working by changing myCustomGameMode and myCustomGameState base class. I found out that if myCustomGameMode base class is GameMode base then myCustomGameState base class has to be GameStateBase( and not GameState )

1 Like

Yup, just got bit by this one. Weird.