UWorld::ServerTravel
APlayerController::ClientTravelServerTravel:
- Seamless
- Non-seamless
n'utilise pas GameModeBase, utilise GameMode.
protected:
UPROPERTY(EditAnywhere, Category = ...)
int NumberOfPlayer = 4;
UPROPERTY(EditAnywhere, Category = ...)
FString LevelToLoad;
public:
APLobbyGameMode() {
bUseSeamlessTravel = !GIsEditor;
// var start with G is global magic
// Seamless doesn't work with the editor
} void APLobbyGameMode::OnPostLogin(AController* NewPlayer) {
Super::OnPostLogin(NewPlayer);
if (GameSate->PlayerArray.Num() >= NumberOfPlayer) {
GetWorld()->ServerTravel(LevelToLoad.Append("?listen"));
}
}
In game mode blueprint, start the level path (LevelToLoad) by the Game repo.
Timer is a GameState, but it is not controlled by player, thus we need a PlayerController.
class APBasePlayerController {
protected:
UFUNCTION(Server, Reliable)
void ServerRequestTime(APlayerController* Requester, float RequestTime);
UFUNCTION(Client, Reliable, WithValidation)
void ClientRequestTime(float RequestTime, float ServerTime);
}
void APBasePlayerController::ServerRequestTime_Implementation(...) {
return (...).getWorldTime(...);
}
bool APBasePlayerController::ServerRequestTime_Validate(...) {
}
void APBasePlayerController::ClientReportTime(float RequestTime, float ServerTimeResponse) {
float RTT = GetWorld()->GetTimeSeconds() - RequestTime;
// the default function is slow
}
void APBasePlayerController::ReceivedPlayer() {
Super::ReceivedPlayer();
if (IsLocalController()) {
ServerRequestTime(this, GetWorld()->getTimeSeconds());
GetWorld()->GetTimerManager().SetTimer(UpdateServerHandle, ...);
// need to add a timer (UE), too
}
}void APBaseGameState::APBaseGameState()
{
PrimaryActorTick.bCanEverTick = false;
}
double APBaseGameState::GetSererWorldTimeSeconds() const {
if (HasAuthority()) {
return GetWorld()->GetTimeSeconds();
}
else {
auto *MyPC = Cast<PBasePlayerController>(GetGameInstance()->Get(...))
}
if (MyPC == nullptr) {
return Super::GetServerWorldTimeSeconds();
}
return MyPC->ServerTime;
}- At
$t=0$ , player ask the time from the server, calculate RTT, latency ; therefore the correct time on server. - (default
Request/Responseimpl is bad, reimplement customizedPlayerController) -
Request/ResponsedansPlayerController - ReceivedPlayer: 1st request, setup timer
- Tick: client update the server time (pseudo)
override GetServerTimeSeconds dans le game state
si on est serveur, World::GetTimeInSec
si on est client, PlayerController custom ServerTime