Travel
Map을 이동하기 위해서는 Travel을 이용해야 한다.
Travel은 크게 Seamless 방식과 non-seamless방식으로 나뉜다.
Seamless 방식은 Player들의 연결 해제 없이 매끄럽게 Map을 이동한다.
매끄러운 이동을 위해 TransitionMap을 이용하는데, TransitionMap이란 목적이 되는 Map으로 이동하기 전에 거쳐가는 Map이다.
쉽게 생각하면 맵을 이동 하면서 로딩화면을 띄운다고 생각하면 된다.
또한, Seamless 방식으로 Map을 이동하면 몇 개의 액터를 지속시킬 수 있다.
다음은 지속시킬 수 있는 액터들이다.
- GameMode 액터 (서버만)
- AGameModeBase::GetSeamlessTravelActorList 를 통해 추가된 액터
- 유효한 PlayerState 가 있는 모든 Controller (서버만)
- 모든 PlayerController (서버만)
- 모든 로컬 PlayerController (서버 및 클라이언트)
- 로컬 PlayerController 에서 호출된 APlayerController::GetSeamlessTravelActorList 를 통해 추가된 액터
non-seamless방식은 클라이언트의 연결을 끊고 다시 연결시키는 방식이다.
연결 해제, 재연결 과정에서 예외가 발생할 수 있기에 추천하는 방식은 아니다.
https://docs.unrealengine.com/4.27/ko/InteractiveExperiences/Networking/Travelling/
ServerTravel
Server에서 실행하는 Travel이다.
ServerTravel을 실행하면 연결되어 있는 모든 Client와 함께 Map을 이동한다.
정확히는 접속된 모든 Client 대해 APlayerController::ClientTravel을 호출한다.
EnableListenServer(true, 7777);
auto World = GetWorld();
if (World)
{
World->ServerTravel("/Game/Splendor/Maps/Menu/Lobby?listen");
}
EnableListenServer는 Listen Server로 동작할 수 있게 해주는 함수이다. (7777은 포트번호이다.)
위의 함수를 CreateSession이 완료되어 델리게이트를 처리하는 함수에서 호출하였다.
ClinetTravel
클라이언트에서 호출되면, 새 서버로 이동합니다.
서버에서 호출되면, 특정 클라이언트더러 새 맵으로 이동하라 이릅니다 (현재 서버에 접속은 유지시킵니다).
IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
if (OnlineSub)
{
IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();
if (Sessions.IsValid())
{
APlayerController* const PlayerController = GetFirstLocalPlayerController();
FString TravelURL;
if (PlayerController && Sessions->GetResolvedConnectString(SessionName, TravelURL))
{
PlayerController->ClientTravel(TravelURL, ETravelType::TRAVEL_Absolute);
}
}
}
2. Session에서 설명했던 OnJoinSessionComplete함수의 일부분이다.
GetResolvedConnectString를 통해 얻은 URL을 통해 ClientTravel을 실행하면 참여한 Session의 Map으로 이동할 수 있다.