120 - Syncing Client and Server Time

This commit is contained in:
Kingsmedia 2022-05-10 11:14:54 +02:00
parent f1558e3a8a
commit 01121ec160
2 changed files with 71 additions and 6 deletions

View File

@ -22,6 +22,8 @@ void ABlasterPlayerController::Tick(float DeltaSeconds)
Super::Tick(DeltaSeconds);
SetHUDTime();
CheckTimeSync(DeltaSeconds);
}
void ABlasterPlayerController::OnPossess(APawn* InPawn)
@ -34,15 +36,56 @@ void ABlasterPlayerController::OnPossess(APawn* InPawn)
}
}
void ABlasterPlayerController::ReceivedPlayer()
{
Super::ReceivedPlayer();
if (IsLocalController())
{
ServerRequestServerTime(GetWorld()->GetTimeSeconds());
}
}
void ABlasterPlayerController::CheckTimeSync(float DeltaSeconds)
{
TimeSyncRunningTime += DeltaSeconds;
if (IsLocalController() && TimeSyncRunningTime > TimeSyncFrequency)
{
ServerRequestServerTime(GetWorld()->GetTimeSeconds());
TimeSyncRunningTime = 0.f;
}
}
float ABlasterPlayerController::GetServerTime()
{
if (HasAuthority()) return GetWorld()->GetTimeSeconds();
return GetWorld()->GetTimeSeconds() + ClientServerDelta;
}
void ABlasterPlayerController::ServerRequestServerTime_Implementation(float TimeOfClientRequest)
{
const float ServerTimeOfReceipt = GetWorld()->GetTimeSeconds();
ClientReportServerTime(TimeOfClientRequest, ServerTimeOfReceipt);
}
void ABlasterPlayerController::ClientReportServerTime_Implementation(float TimeOfClientRequest, float TimeServerReceivedClientRequest)
{
const float RoundTripTime = GetWorld()->GetTimeSeconds() - TimeOfClientRequest;
const float CurrentServerTime = TimeServerReceivedClientRequest + 0.5f * RoundTripTime;
ClientServerDelta = CurrentServerTime - GetWorld()->GetTimeSeconds();
}
void ABlasterPlayerController::SetHUDTime()
{
const uint32 SecondsLeft = FMath::CeilToInt(MatchTime - GetWorld()->GetTimeSeconds());
const uint32 SecondsLeft = FMath::CeilToInt(MatchTime - GetServerTime());
if (CountdownInt != SecondsLeft)
{
SetHUDMatchCountdown(MatchTime - GetWorld()->GetTimeSeconds());
SetHUDMatchCountdown(MatchTime - GetServerTime());
}
CountdownInt = SecondsLeft;
}
@ -54,7 +97,7 @@ void ABlasterPlayerController::SetHUDHealth(float Health, float MaxHealth)
BlasterHUD->CharacterOverlay &&
BlasterHUD->CharacterOverlay->HealthBar &&
BlasterHUD->CharacterOverlay->HealthText;
if (bHUDValid)
{
const float HealthPercent = Health / MaxHealth;
@ -136,7 +179,7 @@ void ABlasterPlayerController::SetHUDMatchCountdown(float CountdownTime)
{
int32 Minutes = FMath::FloorToInt(CountdownTime / 60);
int32 Seconds = CountdownTime - Minutes * 60;
const FString CountdownText = FString::Printf(TEXT("%02d:%02d"), Minutes, Seconds);
BlasterHUD->CharacterOverlay->MatchCountdownText->SetText(FText::FromString(CountdownText));
}

View File

@ -18,6 +18,7 @@ public:
virtual void Tick(float DeltaSeconds) override;
virtual void OnPossess(APawn* InPawn) override;
virtual void ReceivedPlayer() override; // Sync with server clock as soon as possible
void SetHUDHealth(float Health, float MaxHealth);
void SetHUDScore(float Score);
@ -25,12 +26,33 @@ public:
void SetHUDWeaponAmmo(int32 Ammo);
void SetHUDCarriedAmmo(int32 Ammo);
void SetHUDMatchCountdown(float CountdownTime);
// Synced with server world clock
virtual float GetServerTime();
protected:
virtual void BeginPlay() override;
void CheckTimeSync(float DeltaSeconds);
void SetHUDTime();
// Sync time between client and server
// Requests the current server time, passing in the client's time when the request was sent
UFUNCTION(Server, Reliable)
void ServerRequestServerTime(float TimeOfClientRequest);
// Reports the current server time to the client in response to ServerRequestServerTime
UFUNCTION(Client, Reliable)
void ClientReportServerTime(float TimeOfClientRequest, float TimeServerReceivedClientRequest);
// Difference between client and server time
float ClientServerDelta = 0;
UPROPERTY(EditAnywhere, Category = Time)
float TimeSyncFrequency = 10.f;
float TimeSyncRunningTime = 0.f;
private:
UPROPERTY()