Networking/Server Travel2020. 2. 20. 17:17

로비맵에 현제 접속 중인 모든 클라이언트들에게 동시에 게임맵으로 전환(Server Travel)하고 로비맵에서 선택한 캐릭터를 게임맵에서 스폰하는 예

 

로그인 버튼을 누르면 서버측(GameMode)에서 로그인 순서대로 플레이어에게 순번을 부여하면 클라이언트 측의 SaveGame이나 GameInstance 에 저장했다가, 2명이 모두 로그인하면 서버측(GameMode)에서는 Server Travel 명령을 실행하여 모두 클라이언트가 ThirdPersonExampleMap 으로 전환하도록 한다.

Server Travel 후에 실행되는 ThirdPersonGameMode의 OnRestartPlayer 함수에서 SaveGame 이나 GameInstance 로부터 플레이어의 순번을 참조하여 해당 번호의 캐릭터를 스폰하여 3인칭 맵 위에 표시한다

 

 

언리얼 에디터에서 3인칭 프로젝트 템플릿을 사용하여 프로젝트 생성

 

 

2개의 캐릭터 생성

  • ThirdPersonCharacter : 디폴트로 존재하는 캐릭터
  • BP_Blue : ThirdPersonCharacter를 복제하여 BodyColor 만 변경한 캐릭터

 

복제된 캐릭터의 BodyColor 를 변경하기 위해 아래의 Construction Script 참고

 

2개의 레벨 생성(아무것도 없는 Empty 레벨, 3인칭 템플릿 레벨)

  • LobbyMap : 아무것도 없는 로비용 Empty 레벨
  • ThirdPersonExampleMap  : 3인칭 프로젝트 템플릿에 포함된 게임용 레벨
  • 게임맵을 더블클릭하여 에디터에서 열고 월드아웃라이너에서 디폴트로 포함된 Network Player Start를 삭제한다
  • 언리얼 에디터 > 모드 > 배치 >검색창에 Player Start 를 검색하여 드래그하여 레벨에 필요한 플레이어 수만큼 배치한다

 

2개의 GameMode 생성

  • GM_Lobby : Use Seamless Travel 속성 체크
  • 로비맵의 GameMode에디터에서 Default Pawn Class 항목에 None 설정
  • ThirdPersonGameMode (디폴트 생성됨) : Use Seamless Travel 속성 체크
  • 게임맵의 GameMode에디터에서 Default Pawn Class 항목에 Pawn 설정

 

2개의 PlayerController 생성

  • BP_LobbyPlayerController (로비맵에서 사용될 PlayerController)
  • BP_ThirdPersonPlayerController (게임맵에서 사용될 PlayerController)
  • 프로젝트 세팅 항목에서 Editor Startup Map, Game Default MapLobbyMap으로 설정한다

 

SaveGame 블루프린트 클래스 생성(SG_PlayerNumber)

  • Player Number 정수 변수 선언

 

GameInstance 클래스 생성(BP_GameInstance)

  • 여기에서는 GameInstance에 Player Number 정수 값을 저장하여 레벨전환 후에 다시 참조할 것이므로 Player Number 라는 정수변수 1개만 선언한다
  • 프로젝트 세팅 > 맵 & 모드 > Game Instance 섹션의 Game Instance Class항목에 등록한다

 

플레이 설정

  • 언리얼 에디터 > 플레이 버튼 우측 역삼각형 > 고급세팅 > Multiplayer Options > 단일 프로세스 항목 체크해제, 에디터 멀티플레이어 모드 항목에 Play As Client 설정
  • 언리얼 에디터 > 플레이 버튼 우측 역삼각형 > 플레이어 수: 2,    독립형 게임 선택
  • 위와 같이 설정한 후에는 [플레이] 버튼만 누르면 위의 설정대로 실행된다
  • 게임이 실행되면 2개의 윈도우에 각 플레이어의 뷰가 표시되고 키보드와 마우스로 각 캐릭터를 제어할 수 있다
  • ALT + TAB 키를 누르면 제어대상 윈도우를 변경할 수 있다
  • 게임 윈도우의 종료는 ALT + TAB 키를 눌렀을 때 보여지는 섬네일 윈도우의 X 버튼을 누르면 된다
  • 한대의 컴퓨터에서 테스트하면 캐릭터가 각 플레이어마다 동일하게 스폰되므로 2대의 컴퓨터에서 테스트해야 한다
  • 패키징하여 네트워크 환경에서 서버와 클라이언트를 실행하는 방법은 여기를 참조하세요

 

WG_Login 위젯생성 (로비맵의 화면에 표시될 로그인버튼 한개만 필요)

 

 

로비맵에서 사용될 PlayerController

 

 

LobbyPlayerController의 멤버변수 Player Number변수복제 노티파이 함수의 내용

 

 

로비맵의 게임모드에서 플레이어 2명이 로그인하면 Server Travel 명령을 실행하여 게임맵(ThirdPersonExampleMap)으로 모든 접속된 클라이언트들을 전환한다

 

 

로비용 PlayerController 에서 Player Number 변수를 선언하고 변수복제(Rep Notify)를 설정한다

플레이어가 로그인 버튼을 누른면 서버측에서 로그인 순번을 지정하여 Player Number 변수에 저장하므로 Player Number 변수는 변수복제를 사용하여 클라이언트에게 복제되도록 하고 노티파이 함수(On Rep Player Number)도 실행되도록 한다. 변수가 복제되면 SaveGame 을 이용하여 Player Number값을 디스크에 저장한다.

이 값은 나중에 게임맵으로 전환될 때 게임맵의 게임모드에서 읽어들여서 해당 번호의 캐릭터를 스폰하는데 사용한다

 

 

위와 동일하지만 SaveGame이 아닌 GameInstance에 Player Number 를 저장하는 경우

 

 

게임맵의 GameMode에서는 우선 Choose Player Start 를 오버라이드하여 Player Start 위치에 캐릭터가 생성되도록 준비한다

 

 

게임맵의 GameMode에서 각 플레이어에게 캐릭터를 스폰하여 표시해줄 책임이 있으므로 아래처럼 다양한 방법으로 이전에 선택된 캐릭터를 생성한다. 여기서는 OnRestartPlayer 이벤트 함수를 오버라이드 한 예이다. 이 외에도 Spawn Default Pawn at Transform 이나 Spawn Default Pawn For 를 오버라이드하면 더 간편하게 스폰할 수 있다. 이 페이지 하단에 이들 2개 함수의 사용 예를 추가했다

위에서 사용된 Load Player Number 함수는 게임맵의 PlayerController에 정의된 커스텀 이벤트 함수이며 이 함수는 내부에서 다시 GameMode의 RequestPossess 함수를 호출할 때 자신의 Player Number를 파라미터로 전달한다. Player Number를 받은 GameMode 에서는 해당 번호의 폰을 스폰하여 Possess함수를 호출하는 내용이다

 

 

게임맵에서 사용되는 PlayerController의 전체 내용

 

 

게임맵 GameMode 의 변수 섹션에 폰 클래스 배열을 생성한다

 

 

Server Travel 실행 후 로드되는 게임맵에서 폰을 스폰하는 3가지 방법

  • Server Travel 으로 이동된 맵의 GameMode::OnPostLogin 은 실행되지 않으므로 OnRestartPlayer를 오버로드한다
  • OnRestartPlayer를 오버로드할 때는 스폰 후에 Possess함수를 호출해야 한다
  • OnRestartPlayer를 사용하지 않으려면 Spawn Default Pawn at Transform 이나 Spawn Default Pawn For 를 오버라이드하면 된다. 2개의 함수 모두 OnRestartPlayer보다 간편하고 Possess를 호출할 필요가 없다.
  • OnRestartPlayer 실행 후에 Spawn Default Pawn at Transform 이나 Spawn Default Pawn For 가 자동으로 호출된다. 그러므로 이들 3개 중 한개의 함수만 오버로드하여 폰을 스폰해주면 된다

 

OnRestartPlayer 를 오버로드하여 게임맵에 스폰하는 예

 

게임맵의 GameMode에서 Spawn Default Pawn at Transform 오버로드(GameInstance이용하는 버전)

Spawn Default Pawn at Transform 은 OnRestartPlayer 이후에 자동으로 호출되며 Possess 함수는 사용할 필요 없다

 

위와 동일한 함수이며 SaveGame을 이용하는 버전

 

Spawn Default Pawn For 를 오버로드하여 폰을 생성하는 예

Spawn Default Pawn For는 OnRestartPlayer 이후에 자동으로 호출되며 Possess 함수는 사용할 필요 없다

 

Posted by cwisky