정의
리플리케이션은 서버와 클라이언트 사이에서 데이터와 명령을 주고받는 프로세스를 말합니다.
추가적인 설명
리플리케이션의 주역은 액터(Actor)입니다. 서버는 액터 목록을 유지하고, 클라이언트에서 리플리케이트되도록 마킹된 액터들에 대한 근접 추정치를 유지할 수 있도록 클라이언트를 주기적으로 업데이트합니다.
이때 사용되는 액터 업데이트 방식은 '프로퍼티 업데이트'와, 'RPC' 로 나눠집니다.
프로퍼티 업데이트 : 리플리케이션용 프로퍼티 구성하기
1. 액터의 UPROPERTY() 매크로에 Replicated 지정자 포함하기
2. AActor 클래스의 GetLifetimeReplicatedProps 함수 구현하기
> DOREPLIFETIME(AActor, Owner)
DOREPLIFETIME은 Unreal Engine의 네트워킹 시스템에서 사용되는 매크로입니다. 이 매크로는 주어진 클래스의 특정 속성이 네트워크 상에서 복제(replicate)되어야 함을 명시합니다.
네트워크 게임에서, "복제"란 서버와 클라이언트 간에 게임 상태를 동기화하는 과정을 의미합니다.
예를 들어, 어떤 플레이어가 캐릭터를 움직이면 그 움직임은 서버에 전송되고, 서버는 그 정보를 다른 모든 클라이언트에게 전파합니다. 이렇게 하여 모든 플레이어가 동일한 게임 상태를 볼 수 있습니다.
위 예제에서 DOREPLIFETIME(AActor, Owner)는 AActor 클래스의 Owner 속성을 복제하도록 지시하는 것입니다. 이것은 해당 액터의 소유자(Owner) 정보가 네트워크상의 모든 클라이언트에게 동기화되어야 함을 의미합니다.
따라서 GetLifetimeReplicatedProps 함수 내부에서 여러 개의 DOREPLIFETIME 매크로를 사용하면 해당 액터 클래스 내부에서 어떤 속성들이 네트워크 복제 대상인지 정할 수 있습니다.
3. AActor 클래스의 생성자에서 bReplicates = true; 설정하기
프로퍼티 업데이트 방식으로 리플리케이트하기 위해선, 각 액터의 UPROPERTY() 매크로에 replicated 지정자를 포함해야 합니다.
이렇게 포함된 모든 프로퍼티 목록이 유지되면서 서버는 리플리케이트된 프로퍼티의 값이 변할 때마다 각 클라이언트에 업데이트를 전송하며, 클라이언트는 액터의 로컬 버전에 적용합니다.
이런 업데이트는 서버에서만 받고, 클라이언트는 프로퍼티 업데이트를 서버나 다른 클라이언트로 절대 전송하지 않습니다.
RPC (Remote Procedure Call) : 리플리케이션용 RPC 작성하기
RPC는 로컬에서 호출되지만, 호출한 머신과는 다른 머신에서 원격 실행되는 함수를 말합니다.
이러한 RPC 함수는 네트워크 연결을 통해 클라이언트와 서버 사이에 메시지를 전송할 수 있습니다.
함수를 RPC로 선언하려면 UFUNCTION() 매크로에 Server / Client / NetMulticast 키워드를 붙이면 됩니다.
1. Client : 서버에서 함수 호출 → 클라이언트 실행
2. Server : 클라이언트에서 함수 호출 → 서버 실행
3. NetMulticast : 서버에서 함수 호출 → 서버&연결된 모든 클라이언트에서 실행
NetMulticast 지정자를 사용하는 Multicast RPC는 클라이언트에서도 함수 호출이 가능하지만, 이 경우에는 로컬에서만 실행됩니다.
RPC 작동을 위한 조건
RPC 리플리케이션의 정상 작동을 위해선 몇가지 조건을 지켜야 합니다.
1. RPC 함수는 Actor에서 호출되어야 합니다.
2. Actor는 반드시 replicated 상태여야 합니다.
3. 서버에서 호출 → 클라이언트 실행되는 RPC의 경우(Client 지정자)에는, 해당 Actor를 실제 소유하고 있는 클라이언트에서만 함수가 실행됩니다.
즉, 호출 Actor가 서버에만 존재하고 클라이언트에선 존재하지 않는다면 정상작동되지 못합니다.
4. 클라이언트 호출 → 서버 실행되는 RPC의 경우(Server 지정자), 클라이언트는 RPC가 호출되는 Actor를 소유해야 합니다.
여기서, 클라이언트가 "액터를 소유"한다는 것은 해당 클라이언트가 액터에 대한 특정 권한을 가지고 있음을 의미합니다.
예를 들어, Player Character는 그것을 조종하는 클라이언트에 의해 소유됩니다. 따라서 이 클라이언트는 캐릭터의 움직임을 제어하거나, 캐릭터가 수행하는 행동과 관련된 RPC를 호출할 수 있습니다.
특히 클라이언트에서 호출되어 서버에서 실행되는 RPC 함수의 경우엔, Unreal Engine 네트워크 시스템의 보안 메커니즘이 작동하여 서버에서만 실행 가능한 코드를 임의로 실행하지 못하도록 합니다. 이 때문에 클라이언트가 서버에서 실행되는 RPC를 호출하려면, 해당 액터를 소유하고 있어야 하며, 이것은 일종의 "인증" 과정이 됩니다.
5. Multicast RPC의 조건은 예외적입니다.
5-1. 서버에서 호출되는 경우, 서버에서는 로컬에서 실행될 뿐만 아니라 현재 연결된 모든 클라이언트에서도 실행됩니다.
5-2. 클라이언트에서 호출되는 경우, 로컬에서만 실행되며 서버에서는 실행되지 않습니다.
5-3. 멀티캐스트 이벤트에는 단순한 '스로틀 조절 메카니즘'이 있습니다. 따라서 주어진 액터의 네트워크 업데이트 기간 동안 두 번 이상 멀티캐스트 함수가 리플리케이트되지 않습니다.
> 스로틀 조절 메카니즘
여기서 '스로틀 조절 메카니즘'은 네트워크 트래픽을 관리하기 위한 방식 중 하나로, 너무 많은 데이터가 한 번에 전송되면 네트워크 병목 현상이 일어날 수 있어, 데이터 전송 속도를 조절(스로틀)하여 최적의 성능을 유지하기 위한 것입니다.
프로퍼티 업데이트와 RPC의 차이점
프로퍼티 업데이트와 RPC 사이의 큰 차이점은, 프로퍼티는 변경될 때마다 자동으로 리플리케이트되는 반면, RPC는 실행될 때만 리플리케이트된다는 점입니다.
다른 차이점으론, 프로퍼티 리플리케이션은 신뢰성을 보장하고, RPC는 비신뢰성으로 작동된다는 점입니다.
신뢰성있는 네트워크 통신은 전송된 데이터가 손실, 지연, 순서 변경 없이 정확하게 수신자에게 도달하도록 보장합니다.
프로퍼티 리플리케이션은 액터의 프로퍼티(속성)값들이 정확하고 일관되게 네트워크를 통해 복제(replicate)됨을 의미합니다.
반면, RPC는 비신뢰성이므로 RPC 호출이 원격 머신에서 확실하게 실행되도록 하기 위해선 "Reliable" 키워드를 붙여줘야 합니다.
프로퍼티 업데이트 예시
플레이어의 health 값은 변할 때마다 클라이언트에서 알아야 합니다. 이때는 프로퍼티 업데이트를 통해 health 값이 변경될 때마다 자동으로 리플리케이트되어 전송하는 것이 효율적입니다.
그러나, 프로퍼티 업데이트에서 유념할 것은 health 값이 변하지 않더라도, 해당 값이 변했는지 아닌지를 결정하는데 드는 CPU 비용이 존재한다는 것입니다. 즉, 자주 변경되는 프로퍼티에만 해당 방식을 사용하는 것이 좋습니다.
RPC 예시
각 클라이언트마다 특정 위치에서 폭발이 보이도록 구현하고 싶을 때, RPC 방식을 사용하면 좋습니다. 위치와 반경을 파라미터로 하는 RPC를 선언한 후에, 폭발이 발생할 때마다 그것을 호출해주면 됩니다. 이것을 클라이언트 통신을 위한 프로퍼티 그룹으로 저장하여 프로퍼티 업데이트를 하게된다면, 효율이 약간 떨어질 수 있습니다. 폭발은 프로퍼티로 처리할만큼 자주일어나지 않을 수 있기 때문입니다.
https://docs.unrealengine.com/4.27/ko/InteractiveExperiences/Networking/Actors/
액터 리플리케이션
액터 오브젝트 리플리케이션을 여러모로 살펴봅니다.
docs.unrealengine.com
https://docs.unrealengine.com/4.27/ko/InteractiveExperiences/Networking/Actors/Properties/
프로퍼티 리플리케이션
액터 프로퍼티 리플리케이션 방법에 대한 상세 정보입니다.
docs.unrealengine.com
https://docs.unrealengine.com/4.27/ko/InteractiveExperiences/Networking/Actors/RPCs/
RPC
네트워크를 통한 함수 리플리케이션 지정하기 입니다.
docs.unrealengine.com
'👩🏻💻기초지식 > Unreal' 카테고리의 다른 글
[Unreal] FName, FText, FString (0) | 2023.11.07 |
---|---|
[Unreal] 언리얼 서버 모델 (0) | 2023.08.30 |
[Unreal] 가비지 컬렉션 (Garbage Collection) (0) | 2023.08.16 |
[Unreal] 리플렉션(Reflection) (0) | 2023.08.11 |
[Unreal] 서비스 노드란? (BTService) (0) | 2023.08.09 |