액터 관리

JM·2025년 3월 19일

액터의 연결 제어

PlayerController : 플레이어의 입력을 관리하고 각 클라이언트는 고유한 PlayerController를 가진다.
Owner : 소유 관계를 나타낸다. Actor가 PlayerController 또는 다른 Actor에 의해 '소유'될 수 있다.

PlayerController
 └── Assassin (Actor)
       ├── Knife (Actor)
       └── Shield (Actor)

최상위 OwnerPlayerController이므로 PlayerController가 Assassin과 Knife, Shield를 모두 소유한다.
PlayerController가 더 이상 Assassin 캐릭터를 소유하지 않으면, 해당 연결도 액터와 무기를 소유하지 않는다.

Get Player Controller나 Get Player Character와 같은 노드를 사용해 가져올 때 네트워크 환경에서는 상황에 따라 다른 결과가 나올 수 있다.
Player Index = 0인 Get Player Controller를 호출한다면

  • Listen Server : Listen Server의 PlayerController
  • Dedicated Server : 첫 번째 클라이언트의 PlayerController
  • Client : 클라이언트의 PlayerController

그래서 멀티플레이어 게임 개발 시 다음과 같은 멤버함수를 사용한다.

AActor::GetOwner() : Actor 인스턴스의 Owner반환
APawn::GetController() : Pawn이나 Character 인스턴스의 컨트롤러 반환
AController::GetPawn(): Controller가 소유한 Pawn을 반환
APlayerState::GetPlayerController() : PlayerState 인스턴스를 생성한 PlayerController를 반환
UActorComponent::GetOwner() : 컴포넌트의 오너를 반환


연관성

플레이어에게 얼마나 중요한지에 따라 씬에서 어떤 오브젝트를 표시하거나 업데이트할지를 결정하는 과정

엔진은 여러 요소를 사용해 액터에 발생한 변경사항을 플레이어에게 알리는데, 액터까지의 거리, 가시성, 게임 세계에서의 현재 액터의 활성화 여부를 포함한다.

AActor::IsNetRelevantFor()라는 가상함수를 사용해 액터의 연관성을 테스트한다.

1단계 : 다음 조건에 해당하면 액터는 연관성이 있다.

  • bAlwaysRelevant = true
  • Pawn이나 PlayerController가 액터를 소유
  • 액터가 Pawn 객체
  • Pawn객체가 소음이나 데미지와 같은 액션의 주체

2단계 : 액터의 bNetUseOwnerRelevancy = true 이고 액터에 Owner가 있으면 Owner의 연관성이 사용된다.

3단계 : 액터의 bOnlyRelevantToOwner = true 로 설정돼 있고 1단계를 통과하지 못했다면, 액터는 연관성이 없다.

4단계 : 액터가 다른 액터의 스켈레톤에 연결돼 있으면, 액터의 연관성은 부모 액터의 연관성에 따라 결정된다.

5단계 : 액터의 bHidden = true이고 루트 컴포넌트가 검사중인 액터와 충돌하지 않으면, 액터는 연관성이 없다.

6단계 : AGameNetworkManager가 거리 기반 연관성을 사용하도록 설정된 경우, Net Cull Distance보다 가까우면 액터가 연관성이 있다.

대형 액터를 처리할 때 거리 검사 결과를 잘못 판단하거나, 소리차단이나 주변 소리와 관련된 다른 복잡성을 고려하지 않는 등 완벽하지는 않다.
하지만 근사값은 충분히 좋은 결과를 얻는다.


권한

게임 상태의 특정 측면에 대해 최종 결정권을 갖는 게임 인스턴스

서버는 게임상태에 대한 권한을 가져 플레이어의 이동, 데미지 계산과 기타 게임 메카닉 같은 사항에 대해 서버가 최종 결정을 내린다.
어떤 플레이어든 불이익을 받는 일 없이 모두 일관된 게임 상태를 볼 수 있게 보장한다.

권한 제어

Role, Remote Role로 액터를 복제할 때 제어권한, 액터의 복제 여부 및 복제 방법에 대한 정보를 제공한다.

네트워크 플레이 중에 액터는 다음 네 가지 역할 중 하나를 가질 수 있다.

  • ROLE_Authority : 실행 중인 인스턴스가 해당 액터에 대한 권한을 가진다. (서버의 Role만 가능)
  • ROLE_AutonomousProxy : 실행 중인 인스턴스가 해당 액터의 자율 프록시다.
  • ROLE_SimulatedProxy : 실행 중인 인스턴스가 해당 액터의 로컬 시뮬레이티드 프록시다.
  • ROLE_None : 이 경우 해당 역할은 연관성이 없다.

Role : 로컬 컴퓨터에서 액터의 역할을 지정
Remote Role : 원격 컴퓨터에서 액터의 역할을 지정

Autonomous, Simulated Proxy

과도한 CPU리소스 및 대역폭을 사용하지 않기 위해 서버가 업데이트마다 액터를 복제하지 않고 AActor::NetUpdateFrequency가 결정한 빈도대로 복제한다.

이동 중인 액터를 업데이트할 때도 동일하게 클라이언트는 미리 정의된 간격으로 데이터를 받는다.
액터의 업데이트가 플레이어에게 불규칙해 보이는 문제를 피하기 위해 엔진은 최신 데이터를 기반으로 이동을 예측한다.
이때 ROLE_AutonomousProxy이면 시뮬레이션 프록시가 서버에서 받은 최신 속도를 기반으로 액터의 위치를 지속적으로 업데이트 한다.

PlayerController 객체가 액터를 제어할 때, 역할이 ROLE_AutonomousProxy면 시스템은 실제 플레이어로부터 직접 추가 정보를 받아 좀 더 원활하게 행동을 예측할 수 있다.

0개의 댓글