🌠UE5 채팅 시스템 내용 보완

2025. 3. 23. 19:26·Dev./게임 네트워크

2025.03.17 - [Dev./게임 네트워크] - [TIL_250317] UE5로 채팅 시스템 만들기(멀티플레이 시스템 공부)

 

[TIL_250317] UE5로 채팅 시스템 만들기(멀티플레이 시스템 공부)

2025.03.14 - [Dev./게임 네트워크] - [TIL_250314] 언리얼 네트워크와 객체 통신 이해 [TIL_250314] 언리얼 네트워크와 객체 통신 이해💭회고오늘 학습한 내용은 다음과 같이 3가지로 요약된다...!언리얼 네

raindrovvv.tistory.com


1. PIE(Play In Editor) 환경에서의 게임 로드 순서

🔄 호스트와 클라이언트의 실행 순서 이해하기

언리얼 엔진에서 멀티플레이어 게임을 개발할 때, PIE 환경에서 호스트와 클라이언트가 어떤 순서로 초기화되는지 이해하는 것은 매우 중요하다.

이 그림을 이해하는 것이 가장 중요! PlayerController가 통신의 핵심이라는 것을 알고 있자.
실행순서: 게임모드 ➡️플레이어컨트롤러➡️HUD➡️레벨 블루프린트


🤔왜 Guest라고 뜨지 않고 UserID라고 뜨는 걸까?

즉, 위젯에서 UserID 값인 'Guest'라고 뜨지 않고 Default 값인 UserID를 그대로 보여준다.

레벨 블루프린트의 OnLoginWithID를 봐보자.

OnLoginWithID 에서 보낸 UserID 값을 어디서 받느냐하면, (해당 블프를 더블 클릭하면 된다)


PlayerController에 있는 OnLoginWithID에서 값을 받는다. 그리고 CallOnUserLogin이 실행 되고, UserID 값이 Setting된다.

 

1) 로그인을 알려주는 디스패처 호출(OnLoginWithID). 위젯에 있는 로그인 이벤트가 구독하고 있음.

2) 멤버 변수 UserID 업데이트

로그인 이벤트 : 서버에서 실행(Run On Server)


위젯

이 위젯에 있는 이벤트가 UserID 값을 받지 못하고 있다는 것인데...

이벤트 설정에 대한 설명을 다시 확인해보자.

- Run on Server: 서버에서 실행되는 함수
- Run on Client: 클라이언트에서 실행되는 함수
- Reliable: 메시지 전달을 보장하는 옵션
- Unreliable: 메시지 전달을 보장하지 않지만 오버헤드가 적은 옵션

➡️ Run On Server : 서버에 존재. GameMode 등 서버에서 구동되는 객체에 접근하는 함수

➡️ Run On Owing Client : 특정 플레이어의 클라이언트에 존재. 사용자 위젯 등 Replicate 되지 않는 클라이언트 고유 객체에 접근하는 함수

 

아래 내용도 확인해보자.


호스트(서버) 실행 순서:

  1. Game Instance 생성
  2. Game Mode 생성 (서버 전용 객체)
  3. Game State 생성 (서버에서 생성 후 클라이언트로 복제)
  4. 레벨 로드 (서버 환경)
  5. Player Controller 생성 (서버)⚡
  6. Player Controller 생성 (Host가 사용할 클라이언트)⚡
  7. Player State 생성 (서버에서 생성 후 클라이언트로 복제)
  8. Pawn/Character 생성
  9. 서버의 BeginPlay 이벤트 실행

클라이언트 실행 순서:

  1. Game Instance 생성 (서버와 별도로 독립적 존재)
  2. 레벨 로드 (서버와 동기화)
  3. Game State 복제 (서버에서 데이터 수신)
  4. Player Controller 생성 (클라이언트)⚡
  5. Player State 생성 (서버에서 복제)
  6. Pawn/Character 생성 (서버에서 복제)
  7. 클라이언트의 BeginPlay 이벤트 실행
  8. 서버와 동기화 시작 (Replicated 변수 동기화)

PIE에서 멀티플레이어 테스트 시 "Number of Players" 설정을 2 이상으로 지정하면 여러 클라이언트를 동시에 시뮬레이션할 수 있습니다. 이 때 첫 번째 창은 항상 서버(또는 리슨 서버)가 되며, 나머지는 클라이언트로 작동한다.

📊 서버-클라이언트 객체 비교표

구분 서버 클라이언트
Game Instance 생성됨 (각 클라이언트마다 독립적) 생성됨 (서버와 독립적)
Game Mode 서버에서만 실행됨 존재하지 않음 ❌
Game State 서버에서 생성됨 서버에서 복제됨
Level Blueprint 서버에서 실행됨 클라이언트에서는 실행되지 않음 ❌
Player Controller 서버에서 모든 클라이언트의 Controller 관리 각 클라이언트에서 자신의 Controller만 존재
Player State 서버에서 생성됨 서버에서 복제됨
Pawn / Character 서버에서 생성됨 서버에서 생성 후 복제됨

🗃️ 데이터 저장 위치 선택 가이드

멀티플레이어 게임에서는 데이터를 어디에 저장할지가 매우 중요...!

잘못된 위치에 데이터를 저장하면 동기화 문제나 보안 취약점이 발생할 수 있다.

  • PlayerController는 클라이언트에서 소유하고 있는 데이터를 관리한다 ➡️ (비공유 정보)
  • PlayerState는 모든 클라이언트와 공유해야 하는 플레이어 데이터를 관리한다 ➡️ 점수, 팀 정보, 플레이어 이름 등
  • GameState는 게임 전체 상태를 공유하는 용도로 사용한다 ➡️ 현재 라운드, 남은 시간, 점령 지점 상태 등
데이터 종류 Player Controller Player State Game State
카메라 설정 ✅(클라이언트 개별로 존재) ❌ ❌
플레이어 점수 ❌ ✅(모든 클라이언트와 공유) ❌
현재 게임 시간 ❌ ❌ ✅(모든 클라이언트와 공유)
로컬 UI 상태 ✅(클라이언트 개별로 존재) ❌ ❌

데이터 저장되는 위치가 어디있는지 파악해봤을 때, UI(위젯)은 클라이언트 개별로 존재한다는 것을 알 수 있었다. 따라서 위젯은 Run On Server가 아니기에 Run On Owing Client로 설정해야 올바르게 작동된다!

Run On Owing Client로 설정


2. Player Controller는 어떻게 생성될까? (중요)

언리얼 엔진에서 Player Controller는 플레이어의 입력을 관리하고 게임 내 캐릭터를 제어하는 핵심 객체이다. 서버는 모든 클라이언트의 Player Controller 인스턴스를 관리하며, 다음과 같은 절차로 생성 및 동기화다.

📱 Player Controller 생성 프로세스

  1. PreLogin: 서버에 접근 시도 중인 플레이어를 수락하거나 거부하는 단계. ErrorMessage에 공백이 아닌 문자열을 입력하면 접속이 거부된다. Login 함수 전에 호출되며, 콘텐츠 다운로드 시간에 따라 Login 호출까지 지연될 수 있다.
  2. Login: 클라이언트가 접속 인증을 마치고 로그인할 때 호출된다. 이 단계에서 클라이언트가 사용할 PlayerController가 생성된다.
  3. PostLogin: 로그인 성공 이후 호출되는 함수. 블루프린트에서 OnPostLogin을 구현하여 추가 로직을 넣을 수 있으며, 이 시점부터 PlayerController에서 리플리케이트되는 함수 호출이 안전하다.
  4. HandleStartingNewPlayer: PostLogin 또는 심리스 트래블(레벨 간 원활한 전환) 이후 호출된다. 기본적으로 플레이어의 폰(Pawn)을 생성하는 역할을 하며, 블루프린트에서 오버라이드하여 새 플레이어에 대한 동작을 수정할 수 있다.

💡Player Controller 생성 과정에서 보안 검증이 필요하다면 PreLogin 단계에서 처리.
💡유저 데이터 초기화는 PostLogin에서 하는 것이 안전.

잘못된 시점에 초기화 코드를 넣으면 null 참조 오류나 동기화 문제가 자주 발생한다.

🔗 참고 자료(5.5버전 공식문서에서 내부 구조에 대한 내용이 없다...)

  • 언리얼 엔진의 게임 모드와 게임 스테이트
  • 클라이언트-서버 모델
  • Can Someone Help Me Understand Controllers In Multiplayer
  • Run on server / Run on owning client 잘 구분하여 쓰기
 

Run on server / Run on owning client 잘 구분하여 쓰기

강의 예제: 언리얼 엔진에서 리슨 서버 NetMode 로 채팅을 구현해 보는 예제 예제에서 구현한 로직[레벨 블루프린트] BeginPlay  1. IsServer 여부에 따라 플레이어 컨트롤러의 로그인 이벤트 호출    -

jaboy.tistory.com

https://dev0404.tistory.com/68

 

[내일배움캠프 Day58] 채팅 따라하기

Listen Server를 이용해 RPC를 호출해서 채팅을 만드는 강의를 듣고 정리해보았습니다. 전체 Flow서버 사용자가 Host, 클라이언트 사용자는 Guest로 UserID를 할당한다.채널에 참가하면 사용자의 ID를 출

dev0404.tistory.com

 


3. Remote Role과 Authority

멀티플레이어 게임에서 네트워크 객체의 권한과 역할을 관리하는 것은 매우 중요. 언리얼 엔진은 Remote Role과 Authority라는 개념을 통해 이를 효과적으로 관리한다.

🌐 Remote Role 이해하기

Remote Role은 네트워크에서 액터(Actor)가 어떻게 동작하는지 정의.

값 (ENetRole)
설명
ROLE_None 네트워크에서 복제되지 않음 (싱글플레이어 또는 네트워크 미사용)
ROLE_SimulatedProxy 클라이언트에서 서버의 액터를 복제해서 시뮬레이션 (입력 불가)
ROLE_AutonomousProxy 클라이언트에서 직접 조작하는 액터 (예: 플레이어 캐릭터)
ROLE_Authority 서버에서 실행 중인 객체

✨GetRemoteRole() == ROLE_None이라는 것은 클라이언트에서 서버로만 메시지를 보낼 수 있도록 제한한다는 의미.

 


🔑 Authority 개념

HasAuthority는 객체(Actor)가 서버에서 실행되고 있는지 여부를 판단하는 데 사용.

  • HasAuthority == true ➡️이 객체는 서버에서 실행 중이다(리슨 서버 또는 전용 서버).
  • HasAuthority == false ➡️이 객체는 클라이언트에서 실행 중이다.

HasAuthority 체크는 멀티플레이어 게임에서 중요한 게임 로직이 항상 서버에서만 실행되도록 보장하는 필수적인 안전장치이다...! 클라이언트 치팅 방지의 첫 번째 방어선이라고 할 수 있다.

📋 Remote Role과 Authority : OnOff 테스트

해당 테스트를 통해 플레이어 컨트롤러의 갯수?를 알 수 있다.

역할  HasAuthority() GetRemoteRole() 생성되는 개수
서버가 관리하는 호스트의 PlayerController true ROLE_Authority 1
호스트가 직접 조작하는 PlayerController (클라이언트 역할) false ROLE_None 1
클라이언트 1의 PlayerController false ROLE_AutonomousProxy 1
서버가 관리하는 클라이언트 1의 PlayerController
(서버에서 복제한 클라이언트 1의 PlayerController)
true ROLE_Authority 1
💡 멀티플레이어 코드에서는 항상 "Switch Has Authority" 노드로 시작하는 습관을 들이자. 서버와 클라이언트의 동작을 명확히 구분하면 디버깅이 훨씬 쉬워진다. 특히 중요한 게임 로직(피해 계산, 점수 부여 등)은 반드시 서버 권한 체크 후 실행하도록 설계해야 한다.

🤔 정리

엔진 기여자의 답변(추측)

  • 서버는 각 플레이어마다 PlayerController를 생성하여 <게임 로직과 데이터>를 처리한다.
  • 클라이언트는 자신만의 PlayerController를 통해 로컬 입력(키보드, 마우스)과 상호작용을 처리한다.
  • 다른 플레이어들의 캐릭터는 서버로부터 복제되어 화면에 나타나지만, 각 캐릭터의 PlayerController는 클라이언트에 생성되지 않는다(당연히 그래야지ㅇㅇ)
  • Dedi- Server는 각 플레이어에 대한 컨트롤러들을 가지고 있지만, 플레이어로서 작동하지 않으므로 로컬 컨트롤러는 없다. 각 클라이언트는 자신의 PlayerController만 가지고 있다.
  •  Listen Server에서의 Host는 서버와 클라이언트를 동시에 실행하므로 두 개의 PlayerController를 가진다. 하나는 클라이언트 컨트롤러, 하나는 서버 컨트롤러. 다른 클라이언트들은 자신만의 컨트롤러를 가진다.
  •  

4. 딜레이와 롤백: 네트워크 지연 보상 기법

멀티플레이어 게임에서 네트워크 지연은 피할 수 없는 문제...! 이를 보상하기 위한 두 가지 주요 접근법이 있다.

 

⏱️ 딜레이 보상 (Delay Compensation)

딜레이 보상은 네트워크 지연 시간을 고려하여 게임 상태를 조정하는 방식.

클라이언트의 명령이 서버에 도달하는 시간을 계산하고, 그 시간만큼 과거의 게임 상태를 참조하여 명령을 처리한다.

 

주요 특징:

  • 서버가 과거 상태를 기반으로 판정
  • 적중 판정 등에 유리함
  • 구현이 비교적 간단함
  • 높은 지연 시간에서는 한계가 있음

↩️ 롤백 넷코드 (Rollback Netcode)

롤백은 클라이언트의 예측 입력을 기반으로 게임을 진행하다가, 서버의 실제 상태와 불일치할 경우 게임 상태를 '롤백'하여 재계산하는 기법.

 

주요 특징:

  • 클라이언트가 입력 지연 없이 즉각 반응
  • 불일치 발생 시 게임 상태 재계산
  • 구현이 복잡하지만 사용자 경험이 우수함
  • 격투 게임, FPS 등 빠른 반응이 필요한 장르에 적합

🎮 실제 적용 사례

현대 격투 게임에서는 롤백 넷코드가 중요한 요소로 자리 잡고 있다고 한다. 이는 플레이어의 입력이 즉각적으로 화면에 반영되어 지연 느낌 없이 게임을 즐길 수 있게 해주기 때문이다. 언리얼 엔진에서도 롤백을 활용한 스킬 구현이 가능하며, 이를 통해 보다 반응성 높은 멀티플레이어 경험을 제공할 수 있다. 

 

롤백 넷코드는 구현이 복잡하지만, 좋은 사용자 경험을 제공다. 특히 격투 게임이나 FPS 같은 반응성이 중요한 장르에서는 필수적이다. 단, 게임 상태가 복잡하고 객체 수가 많을수록 롤백의 계산 부담이 커지므로 성능 고려가 필요하다.

💡 딜레이와 롤백 중 선택할 때는 게임 장르와 목표 유저 경험을 고려하자. 턴제 또는 전략 게임은 딜레이 보상만으로도 충분할 수 있지만, 액션 게임이나 격투 게임은 롤백 방식이 훨씬 나은 경험을 제공힌다.

➡️ 현대 격투게임에서 중요한 이유

 

'Dev. > 게임 네트워크' 카테고리의 다른 글

[TIL_250318] 언리얼 C++로 BluePrint 라이브러리 추가  (0) 2025.03.18
[TIL_250317] UE5로 채팅 시스템 만들기(멀티플레이 시스템 공부)  (0) 2025.03.17
[TIL_250314] 언리얼 네트워크와 객체 통신 이해  (0) 2025.03.14
[TIL_250313_1] 언리얼 소스 코드 빌드하기  (0) 2025.03.13
[TIL_250312] 온라인 게임과 네트워크 구성 이해  (0) 2025.03.12
'Dev./게임 네트워크' 카테고리의 다른 글
  • [TIL_250318] 언리얼 C++로 BluePrint 라이브러리 추가
  • [TIL_250317] UE5로 채팅 시스템 만들기(멀티플레이 시스템 공부)
  • [TIL_250314] 언리얼 네트워크와 객체 통신 이해
  • [TIL_250313_1] 언리얼 소스 코드 빌드하기
raindrovvv
raindrovvv
raindrovvv 님의 블로그 입니다.
  • raindrovvv
    raindrovvv 님의 블로그
    raindrovvv
  • 전체
    오늘
    어제
    • 분류 전체보기 (102) N
      • Dev. (95) N
        • UE 언리얼 엔진 (49)
        • Unity 유니티 (0)
        • Wwise 와이즈 (7)
        • 게임 네트워크 (8)
        • 그래픽스 Graphics (22)
        • 프로젝트 (5) N
        • 기타 개발 관련 (4)
      • Computer Science (0)
        • 하드웨어 HW (0)
        • 소프트웨어 SW (0)
        • 통신 (0)
        • 데이터 (0)
      • 블로그 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Git
    깃
    AI
    unrealengine
    UE
    고라니
    Wwise
    그래픽스
    게임개발
    언리얼
    셰이더
    게임사운드
    게임네트워크
    게임
    네트워크
    Unreal
    머티리얼
    언리얼엔진
    게임음향
    TA
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
raindrovvv
🌠UE5 채팅 시스템 내용 보완
상단으로

티스토리툴바