언리얼 네트워킹 개요

Taegang Yun·2023년 7월 20일
0

프로젝트에 언제든지 멀티플레이어 기능이 필요한 가능성이 있는 경우 프로젝트 시작부터 멀티플레이어를 염두에 두고 모든 게임플레이를 구축하는 것이 좋다.

언리얼 엔진에서 멀티플레이어용으로 프로그래밍된 모든 게임플레이는 여전히 싱글 플레이어에서 작동한다.

따라서 프로젝트에 멀티플레이어 기능이 전혀 필요하지 않다고 완전히 확신하지 않는한 항상 멀티플레이어용으로 프로그래밍 해야 한다.

클라이언트 - 서버 모델

싱글 플레이어 또는 로컬 멀티플레이어 게임에서 게임은 독립 실행형 게임(Standalone) 에서 로컬로 실행된다. 플레이어는 단일 컴퓨터에 입력을 연결하고 액터, 월드 및 각 플레이어의 사용자 인터페이스를 포함하여 게임의 모든 것을 해당 로컬 시스템에 직접 제어한다.

네트워크 멀티플레이어 게임에서 언리얼 엔진은 클라이언트-서버 모델을 사용한다. 네트워크의 한 컴퓨터는 서버 역할을 하고, 멀티플레이어 게임 세션을 호스팅하는 반면, 다른 모든 플레이어의 컴퓨터는 클라이언트로 서버에 연결된다.

게임의 호스트인 서버는 신뢰할 수 있는 하나의 진정한 게임 상태를 보유한다. 즉, 서버는 멀티플레이어 게임이 실제로 벌어지는 곳이다. 각 클라이언트는 서버에서 소유한 Pawn을 원격 제어하여 게임 내 작업을 수행하도록 하기 위해 프로시저 호출을 보낸다. 그러나 서버는 시각적 개체를 클라이언트의 모니터로 직접 스트리밍하지는 않는다. 대신 서버는 게임 상태에 대한 정보를 각 클라이언트에 복제하여, 어떤 액터가 있어야 하는지, 해당 액터가 어떻게 작동해야 하는지, 다양한 변수에 어떤 값이 있어야 하는지 알려준다.

네트워크 게임 플레이 예시

플레이어 1은 무기를 발사하기 위해 로컬 컴퓨터의 입력을 누른다.

  • 플레이어1 의 로컬 Pawn 이 무기 발사 명령을 서버의 상대 Pawn 에 전달한다.
  • 서버에 있는 플레이어 1의 무기가 발사체를 생성한다.
  • 서버는 연결된 각 클라이언트에게 플레이어 1의 발사체 복사본을 생성하도록 지시한다.
  • 서버에 있는 플레이어 1의 무기는 각 클라이언트에게 무기 발사와 관련된 음향 및 시각 효과를 재생하도록 지시한다.

서버에 있는 플레이어 1의 발사체가 무기에서 앞으로 이동한다.

서버는 각 클라이언트에게 플레이어 1의 발사체 움직임을 복제하도록 지시하여 플레이어 1의 발사체 버전도 움직인다.

서버에 있는 플레이어 1의 발사체가 플레이어 2의 폰과 충돌한다.

  • 충돌은 서버에서 플레이어 1의 발사체를 파괴하는 기능을 트리거 한다.

  • 서버는 자동으로 각 클라이언트에게 플레이어 1의 발사체 사본을 파괴하라고 지시한다.

  • 충돌은 모든 클라이언트에게 충돌에 수반되는 소리와 시각 효과를 재생하도록 지시하는 기능을 트리거한다.

  • 서버에 있는 플레이어 2의 Pawn은 발사체의 충돌로 인해 피해를 입는다.

  • 서버에 있는 플레이어 2의 Pawn은 플레이어 2의 클라이언트에게 손상에 대한 응답으로 화면 효과를 재생하도록 지시한다.

네트워크 모드 및 서버 유형

독립형

게임이 원격 클라이언트의 연결을 허용하지 않는 서버로 실행 중이다. 게임에 참여하는 모든 플레이어는 철저히 로컬 플레이어이다. 이 모드는 싱글 플레이어 및 로컬 멀티플레이어 게임에 사용된다. 로컬 플레이어에 적합하도록 서버 측 로직과 클라이언트 로직을 모두 실행한다.

Client

게임이 네트워크 멀티플레이어 세션의 서버에 연결된 클라이언트로 실행 중이다. 서버 측 논리를 실행하지 않는다.

Listen Server

게임이 네트워크 멀티플레이어 세션을 호스팅하는 서버로 실행 중이다. 원격 클라이언트의 연결을 수락하고 서버에 직접 로컬 플레이어가 있다. 이 모드는 캐주얼 협력 및 경쟁 멀티플레이어에 자주 사용된다.

Dedicated Server

게임이 네트워크 멀티플레이어 세션을 호스팅하는 서버로 실행 중이다. 원격 클라이언트의 연결은 허용하지만 로컬 플레이어가 없으므로 보다효율적으로 실행하기 위해 그래픽, 사운드, 입력 및 기타 플레이어 지향 기능을 버린다. 이 모드는 보다 지속적이고 안전한 대규모 멀티플레이어가 필요한 게임에 사용된다.

listen server는 게임 사본이 있는 모든 사용자가 listen server를 시작하고 동일한 컴퓨터에서 플레이할 수 있으므로 사용자가 자발적으로 쉽게 설정할 수 있다 수신 서버를 지원하는 게임에는 서버를 시작하거나 참가할 서버를 검색하기 위한 인게임 UI가 있는 경우가 많다. 그러나 Listen server를 호스팅하는 플레이어가 서버에서 직접 플레이하기 때문에 공정성과 부정 행위에 대한 우려가 제기된다.

'Dedicated Server'는 더 비싸고 구성학 어려우며 자체 네트워크 연결을 갖춘 게임에 참여하는 모든 플레이어와 별도의 컴퓨터가 필요하다. 그러나 dedicated server에 가입한 모든 플레이어는 동일한 유형의 연결로 게임을 경험하므로 공정성이 보장된다. dedicated server는 로컬 플레이어에게만 해당되는 그래픽을 렌더링하거나 기타 로직을 수행하지 않기 때문에 게임 플레이 및 네트워킹을 보다 효율적으로 처리할 수 있다. MMO, 경쟁 MOBA 또는 빠르게 진행되는 온라인 슈팅 게임이 포함된다.

Actor Replication

replication 은 네트워크 세션에서 서로 다른 시스템 간에 게임 상태 정보를 재생하는 프로세스이다. replication이 올바르게 설정되면 다른 시스템의 게임 인스턴스가 동기화된다. 기본적으로 대부분의 액터는 replication이 활성되어 있지 않으며 모든 기능을 로컬에서 수행한다. bReplicates C++ 액터 클래스의 변수나 액터 블루프린트의 Replicates 설정을 true로 설정하여 주어진 클래스의 액터에 대한 replication을 활성화할 수 있습니다.

Replication 기능

창조와 파괴

복제된 액터의 신롸할 수 있는 버전이 서버에 스폰되면 연결된 모든 클라이언트에서 자신의 원격 프록시를 자동으로 생성한다. 그런 다음 해당 원격 프록시에 정보를 복제한다. 신뢰할 수 있는 액터를 삭제하면 연결된 모든 클라이언트의 원격 프록시가 자동으로 삭제된다.

움직임 복제

신뢰할 수 있는 액터에 Replicate Movement가 활성되어 있거나 C++로 bReplicateMovement 설정되어 있으면 true 자동으로 위치, 회전 및 속도를 복제한다.

변수 복제

복제되는 것으로 지정된 모든 변수는 값이 변경될 때마다 권한이 있는 행위자에서 원격 프록시로 자동으로 복제된다.

구성 요소 복제

액터 컴포넌트는 자신을 소유한 액터의 일부로 replicate한다. 복제되는 것으로 지정된 구성 요소 내의 모든 변수는 복제되며 구성 요소 내에서 호출되는 모든 RPC는 Actor 클래스에서 호출되는 RPC와 일관되게 작동한다.

RPC(원격 프로시저 호출)

RPC는 네트워크 게임에서 특정 기계로 전송되는 특수 기능이다. RPC가 처음에 어떤 시스템에서 호출되는 관계없이 해당 구현은 RPC가 의도한 시스템에서만 실행된다. 이들은 서버(서버에서만 실행), 클라이언트(액터 소유 클라이언트에서만 실행) 또는 NetMulticast(서버를 포함하여 세션에 견결된 모든 머신에서 실행)로 지정될 수 있습니다.

생성, 소멸 및 이동과 같은 일반적인 사용 사례는 자동으로 처리할 수 있지만, 다른 모든 게임 플레이 기능은 복제를 활성화하더라도 기본적으로 자동으로 복제되지 않는다. 복제하려는 변수와 함수를 게임에 적절하게 정확히 지정해야 한다.

액터, 폰 및 캐릭터의 몇 가지 일반적인 기능은 복제되지 않는다.

  • skeletal mesh 및 static mesh component
  • Material
  • animation blueprint
  • particle system
  • Sound emitters
  • Physics object

이들 각각은 모든 클라이언트에서 개별적으로 실행된다. 그러나 이러한 시각적 요소를 구동하는 변수가 복제되면 모든 클라이언트가 동일한 정보를 가지므로 거의 동일한 방식으로 시뮬레이션 한다.

Variable replication

C++매크로를 Replicated또는 ReplicateUsing 지정자를 사용하거나 블루프린트의 디테일 패널에서 복제됨으로 지정하여 변수 및 오브젝트 참조에 복제를 추가할 수 있다. UPROPERTY 신뢰할 수 있는 액터에서 복제된 변수의 값이 변경될 때마다 해당 정보가 자동으로 신뢰할 수 있는 액터에서 세션에 연결된 원격 프록시로 전송된다.

RepNotify

액터가 리플리케이트 정보를 성공적으로 수신한 경우 특정 변수에 대해 호출할 RepNotify 함수를 지정할 수 있다. RepNotify는 변수가 업데이트될 때 로컬에서만 트리거되므로 권위있는 액터의 변수 변경에 대한 응답으로 게임 플레이 로직을 트리거하는 오버헤드가 낮은 방법이다.
ReplicatedUsing C++에서 변수 매크로의 지정자를 사용하거나 UPROPERTY, RepNotify를 사용하도록 블루프린트에서 변수의 복제 설정을 변경하여 이 기능에 접근할 수 있다.

RepNotify는 다른 게임플레이 기능과 관계없이 복제해야 하는 변수에 추가할 수 있으므로 RPC나 복제된 함수를 사용하는 것보다 선호되며, 추가 네트워크 호출을 생성하는 데 상댕한 대역폭을 절약할 수 있다.

Remote Procedure Calls (RPC)

원격 프로시저 호출은 복제된 기능이라고도 한다. 모든 시스템에서 호출할 수 있지만 네트워크 세션에 연결된 특정 시스템에서 구현되도록 지시한다. 세 가지 유형의 RPC를 사용할 수 있다.

RPC 유형

  • Server : 게임을 호스팅하는 서버에서만 호출된다.
  • Client : 함수가 속한 액터를 소유한 클라이언트에서만 호출된다.
  • NetMulticast : 서버 자체뿐만 아니라 서버에 연결된 모든 클라이언트에서 호출된다.

C++에서는 함수를 UFUNCTION 매크로의 Server, Client, NetMulticast 지정자를 제공하여 지정할 수 있고, 코드 구현에서는 _Implementation 의 접미사를 사용한다.

ExampleClass.h

UFUNCTION(Server, Reliable, WithValidation)
void MyFunction(int myInt);
ExampleClass.cpp
void AExampleClass::MyFunction_Implementation(int myInt){
	//Gameplay code goes here
}

Reliability

RPC를 신뢰할 수 있거나 신뢰할 수 없는 것으로 지정해야 한다.
블루프린트에서는 Reliable 설정을 true로 설정하면 함수를 신뢰할 수 있는 것으로 지정할 수 있다.
C++에서는 , RPC의 매크로

profile
언젠간 전문가가 되겠지

2개의 댓글

comment-user-thumbnail
2023년 7월 20일

글 잘 봤습니다, 감사합니다.

1개의 답글

관련 채용 정보