관리 메뉴

기억을 위한 기록들

[UE] 언리얼에서의 네트워킹 과 리플리케이트 / 리플리케이션에 관하여 본문

UnrealEngine

[UE] 언리얼에서의 네트워킹 과 리플리케이트 / 리플리케이션에 관하여

에드윈H 2024. 4. 2. 18:54

언리얼엔진 공식홈페이지에 기반하여 개인적인 정리 목적에 의해 작성되었습니다.

https://dev.epicgames.com/documentation/ko-kr/unreal-engine/networking-overview-for-unreal-engine

 

언리얼 엔진의 네트워킹 개요

멀티플레이어용 네트워크 게임 구성하기

dev.epicgames.com

 

 

로컬 플레이(싱글플레이)의 경우

싱글 플레이 게임이나 로컬 멀티플레이어  게임에서는 게임이 독립형으로 로컬에서 실행되고, 한 컴퓨터에서 액터들과 월드 및 각 플레이어의 UI 등 모든것을 직접 제어한다.

 

예를 들어 서로에게 발사체를 발사하는 게임이 있다고 치자.

 

네트워크 멀티플레이 게임

네트워크의 경우 언리얼엔진에서는 클라이언트-서버 모델을 사용합니다. 네트워크에 있는 하나의 컴퓨터가 서버의 역할을 하고 멀티플레이어 게임 세션을 호스팅하고, 서버에 접속한 다른 모든 플레이어의 컴퓨터는 클라이언트가 됩낟.

 

 

그리고 같은 발사체를 발사하는 경우이다.

 

 

 

위와 같이 로컬플레이의 경우 한 월드에서 같은 계산을 하고 적용이 되는데, 멀티플레이의 경우는 서버를 중심으로 각각의 클라이언트에 일어나는 일들을 동기화 해주어야한다.

그것들과 관련되어 벌어지는 기능이벤트 들에 대해서 관련된 리플리케이션 및 리플리케이트라는 용어로 사용된다.


리플리케이트(Replicate)란?

사전적 의미로는 "사본을 뜨다. 복제하다"라는 의미가 있다. 그리고  데이터베이스에서 주로 사용하는 용어인 리플리케이션이라는 것도 있는데 사전적 의미로는 응답이라는 뜻이 있고, 컴퓨터과학 측면에서는

"데이터 저장과 백업하는 관련이 있는데 호스트 컴퓨터에서 다른 컴퓨터로 복사하는 것인데..."- 리플리케이션 위키백과

 

이렇게 두 단어에 대한 의미로만 봤을 때 복제에 관련된 의미에 가깝다.

 

언리얼에서는 액터 리플리케이션, 컴포넌트 리플리케이션, 함수 리플리케이션 이라는 용어들이 존재하는데, 위의 정의와 비슷하게 서버-클라이언트 사이에서 어떤 데이터들을 서로 주고받아서 데이터를 복제하는 행위들을 위한 것이라고 볼 수 있다.

 

즉, 언리얼엔진에서 리플리케이션이 동작하는 일은 서버상에서 발동되는 함수 혹은 특정 프로퍼티 등에 대해 클라이언트에 자동으로 동기화 해주기 위함이다.

 

아래 이미지와 같이 서버에는 2개의 귀신 캐릭터가 존재하지만, 그중 한 귀신 캐릭터는 액터 리플리케이션이 적용 되지않아 클라이언트 화면에서는 한 캐릭터만 보이고 있는 모습이다.

왼쪽은 서버 실행화면/ 오른쪽은 클라이언트 실행 화면

* 에픽게임즈에서 제공하는 콘텐츠샘플에 "Network_Features"라는 레벨에 샘플 참고.

 


 

적용 방식에는 2가지가 있는데,

 

1. 프로퍼티 업데이트

2. RPC(Remote Procedure Call / 원격 프로시저 호출)

 

두개의 큰 차이점으로는 1번 프로퍼티 업데이트는 어떤 데이터가 변경될 때마다 자동으로 리플리케이트 되는 반면, RPC는 실행될 때문 리플리케이트 된다는 점이다.

 

1. 프로퍼티 업데이트

	class ENGINE_API AActor : public UObject
	{
		UPROPERTY( replicated )
		AActor * Owner;
	};

 

	void AActor::GetLifetimeReplicatedProps( TArray< FLifetimeProperty > & OutLifetimeProps ) const
	{
		DOREPLIFETIME( AActor, Owner );
	}
	AActor::AActor( const class FPostConstructInitializeProperties & PCIP ) : Super( PCIP )
	{
		bReplicates = true;
	}

 

 

 

2. RPC (참고)

리플리케이티드 함수라고도 한다. 모든 컴퓨터에서 호출할 수 있지만, 네트워크 세션에 접속 된 특정 컴퓨터에서 구현되도록 지시한다. 세가지 타입의 RPC를 사용할수 있습니다.

1. 서버 - 서버에서만 실행됩니다.

2. 클라이언트 - 이 액터에 대해 소유중인 클라이언트에서만 실행됩니다.

3. NetMulticast - 서버에 접속된 모든 클라이언트와 서버 자체에서 호출됩니다.

 

RPC 사용하기 - C++

RPC로 선언하려면 UFUNCTION 선언에 알맞는 키워드를 붙여주면 된다.

ex)

	//함수를 서버에서 호출되지만 클라이언트에서 실행되는 RPC로 선언.
	UFUNCTION( Client )
	void ClientRPCFunction();
    
    //클라이언트에서 호출되지만 서버에서 실행되는 RPC 로 선언
   	UFUNCTION( Server )
	void ServerRPCFunction();

	//서버에서 호출된 다음 서버는 물론 현재 연결된 모든 클라이언트에서도 실행되도록 고안된 것입니다.
    // 멀티캐스트 함수를 선언
	UFUNCTION( NetMulticast )
	void MulticastRPCFunction();

 

RPC 사용하기 - 블루프린트

블루프린트에서는 Custom Event에서만 Replicates 체크가 가능합니다.

 


 

신뢰성

RPC를 지정 해줄때에 같이 Reliable 혹은 Unreliable을 지정해주어야 한다. 우선 Reliable를 직역하게되면 "믿을 수 있는" 이라는 의미를 갖고 있다. 반대로 UnReliable  는 "믿을 수 없는" 이라는 의미를 가지고 있다.

 

해당 키워드를 붙이는 이유는 Reliable  를 붙이게 되면 네트워크가 불안정한상태에서도 무조건 호출된다라는 호출에 대해 보장해준다라는 키워드 라고 한다.

 

만약에 Reliable라는 키워드가 있으면 네트워크가 불안정해지더라도, 해당 키워드가 붙은 함수는 호출에 대해 보장을 해주고 UnRealiable은 네트워크가 불안정할 시 호출에 대해 보장을 해주지 않겠다는 의미이다. 어떻게 보면 네트워크의 안정성 및 최적화의 측면에서 붙이고 안붙이고 여부가 선정 될 듯 하다.

 

 

블루프린트에서는 함수와 이벤트는 기본적으로 비신뢰성으로 가정되고, 디테일 패널에서 true로 지정해주어야한다. C++에서는 UFUNCTION 안에 키워드를 같이 포함해주어야한ㄷ.

	UFUNCTION(Server, Reliable)
	void MyFunction(int myInt);

 

 

 

참고자료 : 

https://www.youtube.com/watch?v=JOJP0CvpB8w&t=810s