Replication doesn't seem to work from within a timer

Hi,

I need the following scenario:

  • server computes dice total in a timer

  • dice total is replicated with notification

  • on replication notification, client updates its HUD to display the dice total

When the dice total is modified manually, the replication/notification works well.

But as soon as i modify it in a timer, the mecanism doesn’t work any longer.

In the code below:

  • the HUD is updated only on the server.

  • If i put the RealTimeDiceTotal+=1 instruction in any other function than the timer, the client HUD is updated correctly.

So it looks like the replication is not triggered when modified from a timer.

Am i doing anything forbidden ?

Just in case you’re wondering: using a tick is not a solution here: the real computation of RealTimeDiceTotal involves the sum of a large TArray of int32, which would certainly slow things down, hence the use of a timer.

Thanks

Cedric

header:

UPROPERTY(ReplicatedUsing = OnRep_RealTimeDiceTotal)
	int32 RealTimeDiceTotal;

cpp:

void AyagPlayerController::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	DOREPLIFETIME(AyagPlayerController, RealTimeDiceTotal);
}

void AyagPlayerController::BeginPlayingState()
{
	Super::BeginPlayingState();

	if (Role == ROLE_Authority)
	{
		FTimerHandle UpdateRealTimeDiceHandle;
		FTimerDelegate UpdateRealTimeDiceDelegate = FTimerDelegate::CreateUObject(this, &AyagPlayerController::UpdateRealTimeDiceTotal);
		GetWorld()->GetTimerManager().SetTimer(UpdateRealTimeDiceHandle, UpdateRealTimeDiceDelegate, .1f, true);
	}
}

void AyagPlayerController::UpdateRealTimeDiceTotal()
{
	if (Role == ROLE_Authority) // useless but just to be sure
	{
		// in the real code the update is more complicated^^
		RealTimeDiceTotalTmp = RealTimeDiceTotal + 1;
		RealTimeDiceTotal = RealTimeDiceTotalTmp;
		OnRep_RealTimeDiceTotal();
	}
}

void AyagPlayerController::OnRep_RealTimeDiceTotal()
{
	if (IsLocalPlayerController())
	{
		// update HUD
		AYagHUD* ThisHUD = Cast<AYagHUD>(GetHUD());
		if (ThisHUD) ThisHUD->YagHUDWidget->YagDiceTotalWidget->SetText(FText::FromString(FString::FromInt(RealTimeDiceTotal)));
	}
}

Sorry about the alert, my bad.

I found in the doc that BeginPlayingState is called when the pawn is possessed, which means only on the first PC.

I moved the timer from BeginPlayingState to BeginPlay and it works.

Cheers

Cedric

Hey ,

Our posts must have crossed each other :slight_smile:

Case solved, my fault, i was using BeginPlayingState, which apparently wasn’t such a good idea^^

Moved the timer in BeginPlay and everything’s smooth now.

Thanks though !

Cheers

Cedric

Hey -

Does the code you posted compile successfully or are there errors? Could you post what the errors are if there are any? Can you reproduce the same behavior in a new project? If so please detail the steps to do so?

Cheers

Glad to hear you were able to solve the problem. Best of luck in your project.

Thanks , it’s starting to take shape.

UE4 is a fantastic software, you guys are doing an amazing job !

Cheers

Cedric