본문으로 건너뛰기
Unreal Engine 멀티플레이LESSON 06

NetMode로 현재 실행 환경 확인하기

난이도입문 → 초급
예상 시간55분
선수지식5강의 PIE 테스트 프로필

6강. NetMode로 현재 실행 환경 확인하기

1. 이번 강의에서 해결할 문제​

HasAuthority()만 출력하면 현재 World가 리슨인지 데디케이티드인지, Actor가 없는 UObject나 Subsystem에서 어떤 환경인지 알기 어렵습니다. 로그가 [Server]라고만 되어 있으면 리슨 호스트와 별도 서버를 혼동하고 로컬 화면 의존을 놓칩니다.

2. 학습 목표​

3. 핵심 개념​

NM_Standalone은 네트워크 연결 없이 로컬에서 권한을 가진 실행입니다. NM_ListenServer는 화면과 로컬 플레이어가 있는 서버, NM_DedicatedServer는 화면이 없는 서버, NM_Client는 원격 서버에 접속한 클라이언트입니다. NetMode는 World 수준의 실행 형태이고 Role은 개별 Actor 복사본의 역할입니다.

처음 등장하는 진단 용어​

용어답하는 질문주의할 점
World현재 레벨·Actor·네트워크 드라이버가 속한 실행 공간은 무엇인가PIE 한 프로세스에도 World가 여러 개일 수 있습니다.
NetMode이 World는 Standalone·Listen Server·Dedicated Server·Client 중 무엇인가개별 Actor의 소유자나 Role을 알려 주지 않습니다.
LocalRole이 머신에 존재하는 해당 Actor 복사본의 네트워크 역할은 무엇인가같은 World 안에서도 Actor마다 다릅니다.
Local Control이 Pawn·Controller가 이 머신의 입력과 카메라 주체인가Authority와 같은 뜻이 아닙니다.
PIE Instance ID한 Editor 프로세스 안의 테스트 World를 어떻게 구분할 것인가패키징 빌드의 영구 서버 ID로 사용하지 않습니다.

NetMode는 함수가 실행되는 프로세스 역할을 확인할 때 씁니다. 서버 전용 저장이나 화면이 필요한 코드의 전제 조건을 검사하는 데 유용합니다. 반면 “이 Actor의 값을 누가 확정하는가”는 Authority, “어느 클라이언트로 RPC를 보낼 것인가”는 Ownership으로 판단해야 합니다.

관찰 창World NetMode로컬 플레이어화면·입력
StandaloneStandalone있음있음
Listen HostListenServer있음있음, 서버도 함께 실행
원격 클라이언트Client있음있음, 서버 권한 없음
Dedicated ServerDedicatedServer없음렌더링 화면과 로컬 입력 없음

4. 단계별 실습​

파일 경로: Source/CaptureArena/Debug/CaptureNetDebug.h

CaptureNetDebug.h
#pragma once

#include "CoreMinimal.h"

namespace CaptureNetDebug
{
inline const TCHAR* NetModeToString(const UWorld* World)
{
if (!World) return TEXT("NoWorld");

switch (World->GetNetMode())
{
case NM_Standalone: return TEXT("Standalone");
case NM_DedicatedServer: return TEXT("DedicatedServer");
case NM_ListenServer: return TEXT("ListenServer");
case NM_Client: return TEXT("Client");
default: return TEXT("Unknown");
}
}

inline FString Context(const UObject* Object)
{
const UWorld* World = Object ? Object->GetWorld() : nullptr;
const FString ObjectName = GetNameSafe(Object);
const int32 PieId = World && World->GetPackage()
? World->GetPackage()->GetPIEInstanceID()
: INDEX_NONE;
return FString::Printf(TEXT("[%s][PIE=%d][%s]"),
NetModeToString(World), PieId, *ObjectName);
}
}

유틸리티 코드 한 줄씩 이해하기​

  1. World == nullptr을 먼저 처리해 생성자·종료 과정처럼 World가 없는 시점의 진단 코드가 크래시를 만들지 않게 합니다.
  2. World->GetNetMode()는 World 단위 실행 형태를 반환합니다. Actor의 HasAuthority() 결과를 문자열로 바꾸는 코드가 아닙니다.
  3. Context는 전달받은 UObject에서 World를 찾으므로 Actor뿐 아니라 World를 제공하는 Subsystem·Widget에서도 재사용할 수 있습니다.
  4. GetNameSafe는 null 객체에도 안전한 이름을 반환합니다.
  5. GetPIEInstanceID()는 Single Process PIE의 여러 World를 로그에서 분리합니다. PIE가 아니면 INDEX_NONE일 수 있습니다.
  6. 이 함수는 진단 문자열만 만들며 게임 규칙을 결정하지 않습니다. 로그 포맷에 의존해 서버 권한을 판단하지 마세요.

사용 예

CaptureArenaCharacter.cpp
#include "Debug/CaptureNetDebug.h"

UE_LOG(LogTemp, Display, TEXT("%s BeginPlay LocalRole=%s Local=%d"),
*CaptureNetDebug::Context(this),
*UEnum::GetValueAsString(GetLocalRole()),
IsLocallyControlled());

최소 재현 환경과 예상 로그​

Play 설정에서 Player 수를 2, Net Mode를 Play As Listen Server, Single Process를 켠 뒤 Character 한 개의 BeginPlay 로그를 수집합니다. 정확한 객체 접미사는 실행마다 달라지지만 문맥은 다음처럼 구분돼야 합니다.

[ListenServer][PIE=0][BP_CaptureArenaCharacter_C_0] ... Authority ... Local=1
[ListenServer][PIE=0][BP_CaptureArenaCharacter_C_1] ... Authority ... Local=0
[Client][PIE=1][BP_CaptureArenaCharacter_C_0] ... AutonomousProxy ... Local=1
[Client][PIE=1][BP_CaptureArenaCharacter_C_1] ... SimulatedProxy ... Local=0

Actor 생성·Possess 순서에 따라 이름과 초기 Role 로그 수는 달라질 수 있습니다. 한 줄만 보고 결론 내리지 말고 World NetMode, PIE ID, Actor 이름, LocalRole, Local Control을 한 묶음으로 비교합니다.

로그에 비밀 토큰, 플랫폼 계정 식별자나 세션 인증 데이터를 남기지 않습니다. Player 이름도 공개 로그에 필요한지 검토하고 테스트 닉네임을 사용합니다.

5. 코드가 동작하는 이유​

UObject의 GetWorld()가 유효한 시점에 World NetMode를 읽으면 Actor가 아닌 Subsystem과 Widget 경계에서도 실행 환경을 표시할 수 있습니다. PIE ID는 한 프로세스 안의 여러 World를 구분합니다. Role과 로컬 제어 여부를 별도로 붙이면 “서버인가”와 “이 화면의 입력 주체인가”를 섞지 않습니다.

6. 자주 하는 실수와 해결법​

7. 직접 실습​

실습 목표​

동일한 BeginPlay 코드가 네 실행 환경에서 어느 World·Actor 복사본에서 실행되는지 로그로 구분합니다.

시작 전 상태​

Output Log를 비우고 로그에 NetMode, PIE ID, 객체 이름, LocalRole, IsLocallyControlled가 모두 포함됐는지 확인합니다. 실제 계정 정보 대신 PIE 테스트 객체만 사용합니다.

1단계: 따라 하기​

Standalone에서 한 번 실행합니다. World는 Standalone이고 로컬 Pawn은 Local Control이 참이어야 합니다. Standalone의 Authority를 네트워크 서버 접속 성공으로 해석하지 않습니다.

2단계: 값 바꿔 보기​

2인 Listen Server PIE로 바꾸고 Host·Client 창에서 자기 Character와 상대 Character 로그를 표에 적습니다. Host 자기 Character는 Authority와 Local이 동시에 참일 수 있습니다.

3단계: 직접 적용​

Run Dedicated Server를 켠 프로필에서 서버와 두 Client를 실행합니다. 서버 World는 DedicatedServer이고 모든 Pawn의 Local Control이 거짓이어야 합니다. Client에는 각각 자기 Autonomous Proxy와 상대 Simulated Proxy가 있어야 합니다.

4단계: 스스로 확인​

막혔을 때​

증상원인확인 방법과 해결
모든 로그가 StandalonePIE 네트워크 프로필이 StandaloneAdvanced Play Settings의 Net Mode와 Player 수를 확인합니다.
여러 창 로그를 구분할 수 없음PIE ID·객체 이름 누락Context 문자열을 모든 핵심 로그 앞에 붙입니다.
생성자 로그가 NoWorldWorld 연결 전 진단생성자는 기본값만 설정하고 네트워크 진단은 BeginPlay 이후로 옮깁니다.
Dedicated Server에서 UI 접근 오류화면이 없는 서버에서 로컬 UI를 가정IsRunningDedicatedServer 또는 NetMode 정책으로 화면 코드를 분리하고 Controller 소유 Client에서 UI를 생성합니다.

8. 이해 점검 질문 3개​

9. 핵심 요약​

다음 강의 연결​

다음 강의: Authority, Role, 로컬 플레이어 판별에서는 이 로그 문맥을 이용해 서버 규칙·소유 Client 입력·다른 Client 표현 코드를 실제 실행 위치로 분리합니다.

MINI QUIZ

NetMode로 현재 실행 환경 확인하기 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“NetMode로 현재 실행 환경 확인하기” 내용을 실제 작업에 적용한 설명으로 가장 알맞은 것은 무엇인가요?
  2. 문제 2“NetMode로 현재 실행 환경 확인하기” 실습 중 ‘VeryVerbose 네트워크 로그를 항상 켬’ 상황을 발견했습니다. 본문과 일치하는 설명은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

6강. NetMode로 현재 실행 환경 확인하기 미완료 상태