토이프로젝트를 준비하며 프로젝트 설계시 고려해야하는 부분이 여러가지 있었습니다.

객체 관리, 게임모드, UI 등등 다양한 부분에서 설계를 해야했지만, 게임 장르 및 플레이 타입에 대해 가장 먼저 고민하게 되었습니다.

그 중 멀티플레이를 목적으로한 프로젝트 개발을 결정하게 되었으며, 멀티플레이 환경에서 서버-클라이언트간 어떻게

데이터를 처리하는지에 대해 알아보며 언리얼의 RPC, 리플리케이션, POD 등 다양한 용어들을 학습하게 되었습니다.

그 중 가장 멀티플레이 환경에서 데이터를 동기화하는 방법인 리플리케이션에 대해 알아보도록 하겠습니다.

 

리플리케이션 (Replication)

  • 멀티플레이어 환경을 구축할 때 서버와 클라이언트 간의 데이터를 동기화 하는 기능
  • 서버가 권한(Server Authority)을 가지며, 이를 기반으로 리플리케이션 시스템 사용
    • 게임 서버가 진짜 상태를 결정하고, 이를 클라이언트에 전송하는 방식
    • Ex) Player1 이동 -> 서버 : 이동에 대한 결과 -> Player 2,3,4... 에게 반영 (동기화)
    • 객체의 속성, 위치, 애니메이션 등 필요한 정보를 클라이언트에 전송
    • 클라이언트는 서버의 정보를 기반으로 화면을 업데이트 한다.
    • 해당 과정을 통해 중요한 게임 로직은 서버에서 실행되며, 클라이언트들은 서버에서 데이터를 받아 로컬에서 표시하는 역할을 한다.
  • 리플리케이션은 액터(Actor)를 기준으로  실행된다. 
  • 리플리케이션 대상은 Object, Component, Property, Function이 될 수 있다.
    • Object : 캐릭터, 아이템, 차량 등
    • Component : Mesh, Audio, Collision 등
    • Property : 객체의 위치, 속도, 체력, 점수 등
    • Function(RPC) : 문열기, 공격 이벤트, 총 발사
  • RPC : 데이터 통신
  • Replicated, Replicated Notify : 데이터 복제

 

리플리케이션 설정 방법 ,종류

 

1. 변수 리플리케이션 (Property Replication)

  • UPROPERTY(Replicated) 설정
  • GetLifetimeReplicateProps 함수 내 리플리케이션 변수 등록
  • Replicated Notify 설정

 

// UPROPERTY Replicated

UPROPERTY(Replicated)
int32 PlayerHealth;

// GetLifetimeReplicatedProps

void AMyCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);
    DOREPLIFETIME(AMyCharacter, PlayerHealth);
}

// Rep Notify
UPROPERTY(ReplicatedUsing = OnRep_PlayerHealth)
int32 PlayerHealth;

UFUNCTION()
void OnRep_PlayerHealth()
{
    // 체력 값이 변경될 때 실행할 로직
}

 

 

2. 함수 리플리케이션 (Func Replication) / RPC(Remote Procedure Call)

  • UFUNCTION(Server/Client/Multicast, Reliable)
    • Server : 서버에서만 실행. (Client -> Server)
      • 공격 요청, 스킬 사용 등의 로직
    • Client : 클라이언트에서만 실행. (Server -> Target Client)
      • HUD 업데이트
    • MultiCast : 서버에서 호출, 모든 클라이언트에 실행 (Server -> All Client)
      • 폭발 이벡트, 애니메이션 재생, 게임 결과 등의 로직
// Server RPC
UFUNCTION(Server, Reliable, WithValidation)
void ServerFire();

// Client RPC
UFUNCTION(NetMulticast, Reliable)
void MulticastExplosion();

// Multicast RPC
UFUNCTION(Client, Reliable)
void ClientShowHUD();

 

 

 

3. 액터 리플리케이션

  • 생성자 { bReplicates = true; , SetReplicateMovement(true);}
    • bReplicates = false시 모든 플레이어가 권한(Authority)를 가지게 되며, 플레이어 1이 이동시 다른 플레이어들도 이동한다.
    • 해당 액터의 Movement를 Replicated하게 해준다.

액터 스폰시 SetReplicates(true);

 

// Constructor Replicated Settings
AMyActor::AMyActor()
{
    bReplicates = true; // 서버가 Authority를 가지게 한다. 서버에 정보를 알리고 모든 Client에 전파할 수 있다.
    SetReplicateMovement(true)  // 해당 액터의 Movement를 Replicated한다.
}

// 액터 스폰시 Replicated
AYourActor::Func()
{
    AMyActor* SpawnedActor = GetWorld()->SpawnActor<AMyActor>(MyActorClass, SpawnLocation, SpawnRotation);
    SpawnedActor->SetReplicates(true);
}

 

 

 

Replicated VS Replicated Notify VS RPC

기능 Replicated Replicated Notify (RepNotify) RPC (Remote Procedure Call)
설명 동기화를 통한 데이터 복제 복제 후 특정 시점에 지정한 함수 호출 즉시 함수 호출, 통신 방식
데이터
변경 방식
서버에서 변경하면 클라이언트가 자동으로 반영 서버에서 변경하면 클라이언트가 반영 + 추가 함수 실행 클라이언트 또는 서버에서 직접 함수 실행
변경 감지 기능   복제된 시점에서OnRep_Func() 호출  
동기화
시점
서버에서 변경되면 다음 네트워크 업데이트 시 자동 동기화 서버에서 변경되면 다음 네트워크 업데이트 시 자동 동기화 후 함수 실행 함수가 호출되는 즉시
사용 예시 플레이어 체력, 점수, 탄약 개수 등 체력 변경 시 UI 업데이트, 특수 효과 실행 공격 실행, 문 열기,
이펙트 재생

 

+ Recent posts