언리얼 멀티플레이 기초 개념

김혁·2025년 8월 22일

다양한 서버의 종류

P2P Server (Peer-to-Peer)

  • 구조 : 모든 클라이언트가 서로 직접 연결하여 데이터를 주고 받음
  • 장점
    • 서버 비용 없음
    • 연결 지연(Latency)이 적을 수 있음
  • 단점
    • 보안 취약
    • 호스트 사망 시 게임 종료

Listen Server

  • 구조 : 한 명의 플레이어가 서버 역할도 수행
  • 장점
    • 빠르게 테스트 가능
    • 서버 비용 없음
  • 단점
    • 호스트가 나가면 게임 종료됨
    • 성능 한계가 있음

Dedicated Server

  • 구조 : 중앙 서버가 모든 클라이언트의 메시지를 수신하고 처리
  • 장점
    • 보안성 높음
    • 안정적인 게임 환경
    • 동기화 정확도 우수
  • 단점
    • 비용(서버 유지비) 발생
    • 데이터가 한 지점에 몰려서 지연 발생 가능

Dedicated Server의 실행 흐름도

실행 흐름

  1. 서버 프로레스 실행
    -> 실행할 때 Open {Level명}?Listen 명령어가 인자로 전달되면 해당 Level을 열어둠
    -> 이때 Socket이 생성되며 다른 PC가 접속 가능하게 함 (Listen 명령어가 없으면 싱글플레이)
    -> Level에 있는 WorldSettings 속성을 통해 GameModeGameState 액터를 생성
  2. 클라이언트가 서버의 IP 주소와 포트 번호로 접속 시도
    -> 서버는 접속 시도하는 클라이언트에게 Level 정보를 넘김
    -> 클라이언트도 해당 Level을 열고, Level을 여는데 성공했다고 서버에게 알림
  3. 클라이언트 전용 PlayerState, PlayerController, PlayerCharacter가 서버에 생성
    -> 해당 액터들이 클라이언트에 복제됨
    -> 서버에 있던 GameState도 복제됨
  4. 또 다른 클라이언트가 접속 시에 2~3번 과정 반복
    -> 클라이언트 간에는 서로의 PlayerState, PlayerCharacter가 복제됨
    -> 해당 복제를 통해 서로의 상태 및 캐릭터를 보이게 됨

서버 환경 설정

  1. Allow Late Joining 체크 -> 게임 시작 후에도 클라이언트 추가 가능
  2. Always on top 체크 -> 새 클라이언트 화면이 항상 위에 뜸
  3. Multiplay Options
    - Launch Separate Server 체크 -> 서버를 따로 띄워줌, 안 하면 에디터 화면이 클라이언트이자 서버
    - Run Under One Process 해제 -> 체크하면 같은 프로세스 내라서 공유하는 에셋이 생겨서 의도하지 않는 동작 발생
    - Net Mode : Play as Client
    - Number of Players : 2 -> 2개 이상의 클라이언트로 검사

언리얼의 멀티플레이 관련 개념 및 용어

NetMode

  • 개념
    • 해당 게임 프로세스가 네트워크 상에서 어떤 역할을 하고 있는지를 의미
    • 싱글(NM_StandAlone), 서버(NM_Listen, NM_DedicatedServer), 클라이언트(NM_Client)
  • 필요성
    • 작성한 로직이 서버에서 돌고 있는지, 클라이언트에서 돌고 있는지를 알아야 함
    • 멀티플레이에서는 같은 코드가 여러 PC에서 동작할 수 있고, 디버깅을 제대로 하기 위해서는 어떤 PC에서 동작하는지 알아야 함
  • 관련 함수
    • ENetMode UNetDriver::GetNetMode() : NetDriver를 통해 넷모드를 받아올 수 있음
  • NetMode에 따른 액터 위치
    • 서버에만 존재하는 액터 : 게임 모드
    • 서버와 개개인의 클라이언트에 존재하는 액터 : 플레이어 컨트롤러
    • 서버와 모든 클라이언트에 존재하는 액터 : 배경 액터와 폰
    • 클라이언트에만 존재하는 액터 : UI

NetConnection

  • 개념
    • 서버-클라이언트가 통신하게 되는 수단인 객체
  • 동작 과정
    • 다른 PC와의 연결이 발생하면 그에 대응하는 UNetConnection 객체가 생성됨
    • 서버에 클라이언트 접속 시
      • 서버에는 ClientConnection 객체가 추가됨
      • 클라이언트에는 ServerConnection 객체가 생성됨
  • 특징
    • UNetDriver는 생성된 UNetConnection 객체를 소유하고 관리하고 있음
      • 서버 PC에 생성된 UNetDriver는 접속한 클라이언트의 수만큼 ClientConnections을 관리
      • 클라이언트 PC에 생성된 UNetDriverServerConnection, 단 하나만을 관리
    • 하나의 ClientConnection은 하나의 PlayerController를 소유
      • PlayerController의 Owner은 ClientConnection
      • PlayerController가 빙의하는 Pawn의 Owner는 해당 PlayerController로 설정
      • 위와 같이 Owner 속성을 연결해서 액터의 NetConnection을 반환받거나 할 수 있음
// UNetDriver.h

UCLASS()
class UNetDriver : public UObject, public FExec
{
	UPROPERTY()
    TObjectPtr<UNetConnection> ServerConnection;
    
    UPROPERTY()
    Tarray<TObjectPtr<UNetConnection>> ClientConnections;
}

NetDriver

  • 개념
    • 언리얼 네트워크 통신에서 로우레벨 동작들을 관리하는 클래스
  • 특징
    • 싱글플레이에서는 UNetDriver 객체가 생성되지 않음
    • 멀티플레이에서만 UWorld::Listen() 함수를 통해 UNetDriver 객체가 생성됨
    • 멀티플레이에 참여하는 각 PC마다 UNetDriver 객체가 생성됨

NetRole

  • NetMode의 경우에서는 월드와 관련된 정보로, 해당 월드가 서버 PC의 월드인지, 클라이언트 PC의 월드인지 구분하기 위함이다.
  • 그 액터가 서버 PC에서 스폰되어서 함수가 서버 PC에서 실행되고 있는지, 클라이언트 PC에서 스폰되어서 함수가 클라이언트 PC에서 실행되고 있는지도 파악해야 한다.
  • 이를 파악하기 위해서 Actor 별로 NetRole 속성을 가지고 있어서, 서버나 클라이언트에서 이 액터를 어떤 권한으로 다루는지 알 수 있다.

Authority & Proxy

  • Authority : 서버에 스폰된 액터의 NetRole 속성은 서버에서는 언제나 Authority로, 서버에서 수행을 해도 된다는 권한을 가진 것을 의미한다.
  • Proxy : Authority인 액터가 클라이언트에 복제되었을 때, 클라이언트에서 복제된 액터의 NetRole 속성 값은 Proxy(허상)로, 실질적인 권한이 없음을 의미한다.

Local Role & Remote Role

  • 로컬 롤 : 현재 동작하는 컴퓨터에서의 NetRole
  • 리모트 롤 : 커넥션으로 연결된 컴퓨터에서의 NetRole

NetRole의 종류

  • None
    • 액터가 존재하지 않음
    • 서버에서 스폰되고 레플리케이션되지 않는 액터. 또는 클라이언트에서 스폰된 액터
  • Authority
    • 게임에 중대한 영향을 끼칠 수 있는 로직 작성이 가능함
  • Autonomous Proxy
    • 서버로부터 수신 받아서 동기화되면서, 서버로 송신도 가능함
    • ex) PlayerController
  • Simulated Proxy
    • 서버로부터 수신 받아서 동기화만 함
    • ex) 다른 플레이어의 PlayerCharacter

중요 함수들

  • 게임에 중대한 영향을 끼치는 데미지 같은 로직은 서버 컴퓨터에서만 실행되어야 한다.
    • AActor::HasAuthority() : 실행되는 곳이 서버 컴퓨터이고, 서버에서 생성된 액터인지 확인하는 함수
  • 또한 입력 관련 로직이나 UI는 Autonomous Proxy에서 수행되어야 함
    • AController::IsLocalController() : Autonomous Proxy 롤을 가지는지 검사

-> 두 함수 모두, 네트워크에 연결되어 있지 않은 StandAlone인 상태에서도 true를 반환

액터별 특징

  • 게임 모드는 HasAuthority() 함수를 호출할 필요가 없음 -> 어차피 서버에만 존재
  • 폰은 Authority, Autonomous Proxy, Simulated Proxy가 혼재되어 있음
  • UI 관련 로직은 클라이언트에서만 수행됨


출처: 팀스파르타 내일배움캠프
profile
게임 개발자를 향해..

0개의 댓글