Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- command not found
- 실습
- 트랜잭션 관리
- OS
- 셰그먼트트리
- 언리얼 커스텀 플러그인
- UnrealMP
- Linux
- 2단계로킹
- UActor
- Unreal
- 1967번
- SQL
- 언리얼 플러그인
- 오손데이터읽기
- Security
- FBX
- 비재귀셰그먼트
- C++
- 5639
- 의미와 무의미의 경계에서
- 민겸수
- 1759번
- 데이터베이스 배움터
- oracle
- 백준
- 백준 1253번
- hackerank
- 1253번
- objtofbx
Archives
- Today
- Total
fatalite
언리얼 소스코드 분석 UWorld::ServerTravel 작성중 본문
World의 Server Travel는 Game Mode의 ProcessServerTravel을 호출
bool UWorld::ServerTravel(const FString& FURL, bool bAbsolute, bool bShouldSkipGameNotify)
{
AGameModeBase* GameMode = GetAuthGameMode();
if (GameMode != nullptr && !GameMode->CanServerTravel(FURL, bAbsolute))
{
return false;
}
// Set the next travel type to use
NextTravelType = bAbsolute ? TRAVEL_Absolute : TRAVEL_Relative;
// if we're not already in a level change, start one now
// If the bShouldSkipGameNotify is there, then don't worry about seamless travel recursion
// and accept that we really want to travel
if (NextURL.IsEmpty() && (!IsInSeamlessTravel() || bShouldSkipGameNotify))
{
NextURL = FURL;
if (GameMode != NULL)
{
// Skip notifying clients if requested
if (!bShouldSkipGameNotify)
{
GameMode->ProcessServerTravel(FURL, bAbsolute);
}
}
else
{
NextSwitchCountdown = 0;
}
}
return true;
}
ServerTravel에서 ProcessClientTravel을 호출
void AGameModeBase::ProcessServerTravel(const FString& URL, bool bAbsolute)
{
#if WITH_SERVER_CODE
StartToLeaveMap();
UE_LOG(LogGameMode, Log, TEXT("ProcessServerTravel: %s"), *URL);
UWorld* World = GetWorld();
check(World);
FWorldContext& WorldContext = GEngine->GetWorldContextFromWorldChecked(World);
// Force an old style load screen if the server has been up for a long time so that TimeSeconds doesn't overflow and break everything
bool bSeamless = (bUseSeamlessTravel && GetWorld()->TimeSeconds < 172800.0f); // 172800 seconds == 48 hours
// Compute the next URL, and pull the map out of it. This handles short->long package name conversion
FURL NextURL = FURL(&WorldContext.LastURL, *URL, bAbsolute ? TRAVEL_Absolute : TRAVEL_Relative);
PRAGMA_DISABLE_DEPRECATION_WARNINGS
FGuid NextMapGuid = UEngine::GetPackageGuid(FName(*NextURL.Map), GetWorld()->IsPlayInEditor());
PRAGMA_ENABLE_DEPRECATION_WARNINGS
// Notify clients we're switching level and give them time to receive.
FString URLMod = NextURL.ToString();
PRAGMA_DISABLE_DEPRECATION_WARNINGS
APlayerController* LocalPlayer = ProcessClientTravel(URLMod, NextMapGuid, bSeamless, bAbsolute);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
World->NextURL = URLMod;
ENetMode NetMode = GetNetMode();
if (bSeamless)
{
World->SeamlessTravel(World->NextURL, bAbsolute);
World->NextURL = TEXT("");
}
else
{
// Switch immediately if not networking.
if (NetMode != NM_DedicatedServer && NetMode != NM_ListenServer)
{
World->NextSwitchCountdown = 0.0f;
}
GEngine->IncrementGlobalNetTravelCount();
GEngine->SaveConfig();
}
#endif // WITH_SERVER_CODE
}
ProcessClientTravel에서, 존재하는 각각의 PlayerController에 ClientTravel을 실행
APlayerController* AGameModeBase::ProcessClientTravel(FString& FURL, bool bSeamless, bool bAbsolute)
{
// We call PreClientTravel directly on any local PlayerPawns (ie listen server)
APlayerController* LocalPlayerController = nullptr;
for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
{
if (APlayerController* PlayerController = Iterator->Get())
{
if (Cast<UNetConnection>(PlayerController->Player) != nullptr)
{
// Remote player
PlayerController->ClientTravel(FURL, TRAVEL_Relative, bSeamless);
}
else
{
// Local player
LocalPlayerController = PlayerController;
PlayerController->PreClientTravel(FURL, bAbsolute ? TRAVEL_Absolute : TRAVEL_Relative, bSeamless);
}
}
}
return LocalPlayerController;
}
Server의 PlayerController는 Client로 RPC인, ClientTravelInternal을 호출
void APlayerController::ClientTravelInternal_Implementation(const FString& URL, ETravelType TravelType, bool bSeamless, FGuid MapPackageGuid)
{
UWorld* World = GetWorld();
// Warn the client.
PreClientTravel(URL, TravelType, bSeamless);
if (bSeamless && TravelType == TRAVEL_Relative)
{
World->SeamlessTravel(URL);
}
else
{
if (bSeamless)
{
UE_LOG(LogPlayerController, Warning, TEXT("Unable to perform seamless travel because TravelType was %i, not TRAVEL_Relative"), int32(TravelType));
}
// Do the travel.
GEngine->SetClientTravel(World, *URL, (ETravelType)TravelType);
}
}
GEngine은 Player Controller 헤더 파일에도 선언되어있지 않은 것을 보니
static으로 전역 선언되어있는 것인가..?
(작성중)