📌 오늘 배운 핵심 요약 (Summary)
언리얼 프레임워크의 핵심인 GameMode, GameState, GameInstance의 생명주기와 역할을 축구장에 빗대어 분석했다. 또한 클래스와 인스턴스의 차이를 바탕으로 한 위젯 생성 원리, 불필요한 네트워크 대역폭 낭비를 막는 레플리케이션 최적화, 그리고 클라이언트와 서버 간의 실전 데이터 통신 흐름을 정리했다.
🛠️ 주요 학습 내용
1. ⚽ 언리얼 프레임워크 3대장 비교 (축구장 비유)
맵(레벨) 이동 및 네트워크 환경에서 혼동하기 쉬운 세 가지 핵심 클래스의 역할을 명확히 분담했다.
- GameMode (밀실 안의 심판장)
- 위치: 오직 서버(Server)에만 존재하며, 클라이언트는 접근할 수 없다.
- 수명: 레벨이 전환되면 파괴된다.
- 역할: 절대적인 보안이 필요한 규칙 통제, 정답 생성, 접속자 번호표 발급, 채점 등 핵심 로직을 전담한다.
- GameState (경기장 대형 전광판)
- 위치: 서버 및 모든 클라이언트에 복제된다.
- 수명: 레벨 전환 시 파괴된다. (GameMode와 생명주기를 같이 함)
- 역할: 스코어, 남은 시간, 시스템 메시지 등 게임 내 모든 유저가 공유해야 하는 공용 데이터를 동기화하고 확성기(Multicast) 역할을 수행한다.
- GameInstance (개인 컴퓨터 본체)
- 위치: 서버와 각 클라이언트 컴퓨터에 독립적으로 1개씩 존재하며, 네트워크로 복제되지 않는다.
- 수명: 게임 프로세스(exe)가 종료될 때까지 파괴되지 않는다. (레벨을 여러 번 전환해도 유지됨)
- 역할: 로비에서 인게임으로 넘어갈 때도 유지되어야 하는 '환경 설정', '누적 경험치' 등 영구적인 데이터를 보관한다.
| 클래스 | 위치 | 수명 | 네트워크 복제 (Replication) |
| GameMode | 서버(Server) 전용 | 파괴되고 새로 생성 | X (불가) |
| GameState | 서버 + 모든 클라이언트 | 파괴되고 새로 생성 | O (자동 복제) |
| GameInstance | 각 유저의 컴퓨터마다 1개 | 파괴 안 됨 (유지) | X (각자 독립) |
2. 🐟 UI 위젯 생성의 "붕어빵 이론" (Class vs Instance)
C++에서 위젯이나 액터를 스폰할 때 변수를 2개씩 짝지어 선언해야 하는 이유를 분석했다.
- TSubclassOf<UUserWidget> NotificationTextWidgetClass; (붕어빵 틀)
- 역할: 블루프린트 에디터에서 어떤 디자인의 위젯을 생성할지 지정하는 설계도 클래스다. 메모리에 실체화되지 않은 추상적인 상태다.
- TObjectPtr<UUserWidget> NotificationTextWidgetInstance; (진짜 붕어빵)
- 역할: 코드를 통해 틀(Class)을 기반으로 메모리에 실제 생성해 낸 객체다. 화면에 출력(AddToViewport())하거나 내부 텍스트를 변경하는 등 직접 제어할 때 사용한다.
3. ♻️ 불필요한 네트워크 낭비 방지 (Replication 최적화)
PlayerState 등의 변수를 동기화(DOREPLIFETIME)할 때 고려해야 할 최적화 원칙을 정리했다.
- 동기화가 필요한 변수: PlayerNameString(이름), CurrentGuessCount(현재 시도 횟수)처럼 게임 중 실시간으로 값이 변하고 다른 유저도 이를 확인해야 하는 데이터는 레플리케이션을 활성화해야 한다.
- 동기화가 불필요한 변수: MaxGuessCount(최대 시도 횟수)처럼 초기화 시점에 값이 정해지고 게임 내내 절대 변하지 않는 상수 성격의 데이터는 복제 명단에 넣을 필요가 없다. 이를 구분하는 것이 서버 대역폭을 절약하는 올바른 설계다.
4. ⚾ 실전 네트워크 데이터 흐름 (숫자 야구 게임 예시)
클라이언트의 채팅 입력부터 서버의 채점, 전체 방송까지 이어지는 통신 파이프라인을 구축했다.
- 데이터 조립 (Client): 클라이언트가 숫자(예: "123")를 입력하면, 조종기(PlayerController)가 자신의 명찰(PlayerState)에서 닉네임을 가져와 문자열을 조립한다. (예: "Player1: 123")
- 서버 전송 (Client ➔ Server): 조종기가 조립된 문자열을 Server RPC를 통해 서버로 전달한다.
- 데이터 파싱 및 채점 (Server): 서버의 GameMode는 문자열의 오른쪽 3글자(RightChop)를 잘라내어 입력값을 추출하고, 내부의 비밀 정답과 비교하여 "1S 1B" 등의 결과를 판정한다.
- 결과 방송 (Server ➔ Client): 서버가 TActorIterator를 활용해 방에 있는 모든 조종기를 순회하며, Client RPC를 호출하여 각 클라이언트 화면에 최종 결과를 출력한다.
🧠 오늘의 회고 (Reflection)
- 게임의 핵심 보안과 로직 통제는 무조건 서버(GameMode)가 중앙 집중적으로 관리해야 함을 확인했다.
- 클라이언트는 자신의 조종기(PlayerController)를 통해 서버에 무전(Server RPC)을 보내는 역할에 그쳐야 하며, 서버가 유저의 데이터(PlayerState)를 직접 관리하고 검증해야 위변조를 막는 안전한 멀티플레이 환경을 구축할 수 있다.
'본캠프 TIL' 카테고리의 다른 글
| 08.19 Unreal 본캠프) 메인 메뉴 UI 구현과 세션 네트워크(LAN/Steam) 예외 처리 (0) | 2026.08.19 |
|---|---|
| 08.06 Unreal 본캠프) 숫자 야구 게임 버그 수정 및 입력 유효성 검사 구현 (0) | 2026.08.06 |
| 07.31 Unreal 본캠프) 언리얼 엔진 멀티플레이 네트워크 핵심 구조 완벽 이해 (0) | 2026.07.31 |
| 07.30 Unreal 본캠프) 언리얼 엔진 네트워크 기초 (0) | 2026.07.30 |
| 07.27 Unreal 본캠프) 스텔스 AI 인지 시스템, 무기 아키텍처 및 델리게이트 디커플링 (0) | 2026.07.27 |