언리얼엔진5/[Part3] 이득우의 언리얼 프로그래밍
[이득우의 언리얼 프로그래밍 Part3 필기] 4. 액터의 역할과 커넥션 핸드셰이킹
Rocketbabydolls
2024. 4. 27. 11:00
서버와 클라이언트에 위치한 액터의 역할
- 클라이언트 - 서버 모델에서는 항상 서버에 있는 액터만이 신뢰됨.
- 이를 Authority(권위)를 가진다고 표현함.
- 클라이언트의 액터는 대부분 서버 액터를 복제한 허상에 불과함.
- 이러한 액터를 Proxy라고 표현함.
로컬 역할과 리모트 역할
- 리슨서버의 경우 플레이어로서 게임에도 참여하므로, 어플리케이션의 게임 로직을 사용한다.
- 어플리케이션의 게임 로직은 서버 액터에 대해서만 게임에 관련된 작업을 수행해야 한다.
- 이를 구분하기 위해 현재 동작하는 어플리케이션에서의 역할을 로컬 역할(Local Role), 커넥션으로 연결된 어플리케이션에서의 역할을 리모트 역할(Remote Role)이라고 한다.
액터 역할의 종류
- None : 액터가 존재하지 않음.
- Authority : 서비스를 대표하는 신뢰할 수 있는 역할. 게임 로직을 수행한다.
- AutonomousProxy : Authority를 가진 오브젝트의 복제품. 일부 게임 로직을 수행함
- SimulatedProxy : Authority를 가진 오브젝트의 복제품. 게임 로직을 전혀 수행하지 않음.
넷모드에 따른 오브젝트 배치
- 서버에만 존재하는 액터 : 게임모드
- 서버와 모든 클라이언트에 존재하는 액터 : 배경 액터와 폰
- 서버와 소유하는 클라이언트에만 존재하는 액터 : 플레이어 컨트롤러
- 클라이언트에만 존재하는 오브젝트 / 애니메이션 블루프린트 및 HUD (UI 등)
오브젝트 배치에 따른 API 의 사용
- 게임 모드는 HasAuthority 함수를 호출할 필요가 없음.
- 폰은 Autonomous와 Simulated가 혼재되어 있음. API 를 사용해 로직을 구분해야 함.
- 애니메이션 재생이나 UI 관려 로직은 클라이언트에만 사용함.(서버는 변경된 속성을 전달하고, 변경된 속성에 따라 애니메이션과 UI를 바꾸도록 설계)
로그 분석
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_None] AABGameMode::Login Begin
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_None] AABPlayerController::PostInitializeComponents Begin
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_None] AABPlayerController::PostInitializeComponents End
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_None] AABGameMode::Login End
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_None] AABGameMode::PostLogin Begin
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_SimulatedProxy] AABPlayerController::OnPossess Begin
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_SimulatedProxy] AABCharacterPlayer::PossessedBy Begin
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_SimulatedProxy] AABCharacterPlayer::PossessedBy No Owner
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_SimulatedProxy] AABCharacterPlayer::PossessedBy Owner : BP_ABPlayerController_C_0
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_SimulatedProxy] AABCharacterPlayer::PossessedBy End
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_SimulatedProxy] AABPlayerController::OnPossess End
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_None] AABGameMode::PostLogin No NetDriver
LogABNetwork: [STANDALONE][ROLE_Authority/ROLE_None] AABGameMode::PostLogin End
LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::PreLogin ============================================================
LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::PreLogin Begin
LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::PreLogin End
LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::Login Begin
LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABPlayerController::PostInitializeComponents Begin
LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABPlayerController::PostInitializeComponents End
LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::Login End
LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::PostLogin Begin
LogABNetwork: [SERVER][ROLE_Authority/ROLE_AutonomousProxy] AABPlayerController::OnPossess Begin
LogABNetwork: [SERVER][ROLE_Authority/ROLE_SimulatedProxy] AABCharacterPlayer::PossessedBy Begin
LogABNetwork: [SERVER][ROLE_Authority/ROLE_SimulatedProxy] AABCharacterPlayer::PossessedBy No Owner
LogABNetwork: [SERVER][ROLE_Authority/ROLE_AutonomousProxy] AABCharacterPlayer::PossessedBy Owner : BP_ABPlayerController_C_1
LogABNetwork: [SERVER][ROLE_Authority/ROLE_AutonomousProxy] AABCharacterPlayer::PossessedBy End
LogABNetwork: [SERVER][ROLE_Authority/ROLE_AutonomousProxy] AABPlayerController::OnPossess End
LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::PostLogin Client Connections: IpConnection_1
LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::PostLogin End
LogABNetwork: [CLIENT1][ROLE_None/ROLE_Authority] AABPlayerController::PostInitializeComponents Begin
LogABNetwork: [CLIENT1][ROLE_None/ROLE_Authority] AABPlayerController::PostInitializeComponents End
LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABPlayerController::PostNetInit Begin
LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABPlayerController::PostNetInit Server Connection: IpConnection_0
LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABPlayerController::PostNetInit End
LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABCharacterPlayer::OnRep_Owner ABCharacterPlayer_0 Begin
LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABCharacterPlayer::OnRep_Owner Owner : BP_ABPlayerController_C_0
LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABCharacterPlayer::OnRep_Owner End
LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABCharacterPlayer::PostNetInit Begin ABCharacterPlayer_0
LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABCharacterPlayer::PostNetInit End
LogABNetwork: [CLIENT1][ROLE_SimulatedProxy/ROLE_Authority] AABCharacterPlayer::PostNetInit Begin ABCharacterPlayer_1
LogABNetwork: [CLIENT1][ROLE_SimulatedProxy/ROLE_Authority] AABCharacterPlayer::PostNetInit End
서버 관점
스탠드얼론에서 컨트롤러 캐릭터 등이 준비되면서 Remote에서 SimulatedProxy 로 변경된다.
다른 클라이언트(1번)이 로그인에 성공하자 컨트롤러를 만들고 캐릭터 관련 설정하는 과정에서 SimulatedProxy 에서 AutonomousProxy 로 바뀜.
클라이언트 관점
PostNetInit 을 통해 값들을 변경시켜 준 후, 서버에서 생성되어있는 컨트롤러에서 하달되는 명령을 통해 본인의 SimulatedProxy 이 조종됌. 각 컨트롤러들의 오너는 서버에서 동기화 된다.
++ )
오토노머스 프록시는 컨트롤러 자체가 부여되지 않는다.
서버가 플레이어로 참여할 경우에 Role 이 authority므로 islocallycontrolled 는 true 반환. 리모트에서는 autonomousproxy 이다.
게임의 준비
- 커넥션을 허용하면 게임을 시작할 수 있도록 클라이언트와 서버는 준비 과정을 거침
- 클라이언트 : 맵 로딩
- 서버 : 클라이언트를 대표하는 플레이어 컨트롤러의 생성
표로 정리해 보았다.
클라이언트 | 서버 | ||
void UPendingNetGame::SendInitialJoin() | |||
최초의 패킷 전송, NMT_Hello 패킷 전달 | |||
void UWorld::NotifyControlMessage() | |||
챌린지 패킷 전송 | |||
void UPendingNetGame::NotifyControlMessage() | |||
챌린지 패킷 받아서 NMT_Login 패킷 전송 | |||
void AABGameMode::PreLogin() | |||
호출됌, NMT_Welcome 패킷 전송 | |||
void UPendingNetGame::NotifyControlMessage() | |||
웰컴패킷 받아서 NMT_Netspeed 패킷 전송 | |||
맵 로딩 클라이언트에서 완료되면 | |||
void UPendingNetGame::SendJoin() 호출 NMT_Join 전송 | |||
SpawnPlayActor() |
|||
실행 (PostLogin 실행) |