PART 6 · 강의 2/3

런타임 PCG

게임 실행 중 동적으로 PCG 콘텐츠를 생성하고 정리하는 Runtime Generation 시스템을 학습합니다.

01

Runtime Generation 개요

Generate at Runtime 모드의 원리와 설정

Runtime Generation은 게임 실행 중 플레이어 근처에서 동적으로 PCG 콘텐츠를 생성하고, 멀어지면 정리하는 시스템입니다. 무한히 확장되는 프로시저럴 월드나, 메모리 효율적인 대규모 환경 구현에 핵심적입니다.

설정 방법

설정 위치
Generation Trigger PCG Component Generate at Runtime
Is Partitioned PCG Component true (권장)
Generation Radii PCG Component 각 그리드 크기별 생성 반경
Cleanup Radius Multiplier PCG Component 정리 반경 배율 (기본 1.5x)
Runtime Generation 생명주기
// 런타임 PCG 생명주기 [플레이어 이동] [Generation Source 범위 진입] → 해당 그리드 셀의 PCG 실행 → 메시/Actor 스폰 [플레이어 범위 내 유지] → 콘텐츠 유지 [Cleanup Radius 밖으로 이동] → 콘텐츠 정리 (Actor 제거) → 메모리 해제 // 생성 반경 < 정리 반경 (Hysteresis) // → 경계에서 반복 생성/삭제 방지 // 예시: Generation Radius = 5000 (50m) // Cleanup Multiplier = 1.5 // Cleanup Radius = 7500 (75m)
02

Generation Source

런타임 생성을 트리거하는 소스 유형

Generation Source 작동 환경 설명
Editor Viewport 에디터 에디터 뷰포트 카메라 위치 기준으로 생성. 에디터에서 미리보기
Player Controller PIE / Standalone 플레이어 위치 기준. 가장 일반적인 런타임 소스
World Partition Streaming PIE / Standalone World Partition 스트리밍 소스와 동기화
PCG Generation Source Component 모든 환경 커스텀 Actor에 부착하여 임의 위치에서 트리거
커스텀 Generation Source 설정
// C++에서 PCG Generation Source Component 추가 UCLASS() class AMyMovingPlatform : public AActor { GENERATED_BODY() UPROPERTY(VisibleAnywhere) UPCGGenerationSourceComponent* PCGSource; AMyMovingPlatform() { PCGSource = CreateDefaultSubobject <UPCGGenerationSourceComponent>("PCGSource"); // 이 Actor가 이동하면 주변 PCG가 자동 생성/정리 } }; // 활용 사례: // - 이동 중인 기차/비행기 주변 환경 동적 생성 // - NPC 군중 주변 디테일 생성 // - 카메라 드론 주변 환경
03

Frustum Culling과 최적화

시야 기반 생성 최적화와 메모리 관리

Frustum Culling

Frustum Culling 옵션을 활성화하면 카메라 시야(Frustum) 밖의 영역에서는 PCG 생성을 건너뜁니다. 플레이어가 보지 않는 뒤쪽 영역의 불필요한 생성을 방지합니다.

최적화 기법 효과 트레이드오프
Frustum Culling 시야 밖 생성 스킵 (~50% 감소) 빠른 회전 시 순간적 빈 영역
Generation Radii 조정 계층별 최적 생성 거리 설정 너무 작으면 팝인 현상
Cleanup Multiplier Hysteresis로 반복 생성/삭제 방지 높으면 메모리 사용 증가
Hierarchical + Runtime 디테일만 런타임, 큰 것은 사전 생성 설계 복잡도 증가
런타임 PCG 최적화 설정
// Hierarchical + Runtime 조합 (권장 패턴) [대형 오브젝트] Grid: 51200 Generation Trigger: Generate On Load // 사전 생성 → HLOD로 원거리 표현 [중형 오브젝트] Grid: 25600 Generation Trigger: Generate On Load // 사전 생성 → World Partition 스트리밍 [소형 디테일] Grid: 12800 Generation Trigger: Generate at Runtime // 런타임 생성 Generation Radius: 15000 // 150m Cleanup Multiplier: 1.5 Frustum Culling: true // 결과: // - 대형/중형: 레벨에 미리 존재, 스트리밍으로 관리 // - 소형: 플레이어 근처에서만 동적 생성/삭제 // - 메모리 사용 최소화 + 시각적 밀도 유지
04

런타임 PCG 디버깅

런타임 생성 문제 진단과 시각화

PCG 디버그 시각화

콘솔 명령 pcg.Debug.DrawCells 1로 런타임에 생성된 셀 범위를 시각화합니다.

Generation 로그

LogPCG 로그 카테고리를 Verbose로 설정하여 생성/정리 타이밍을 추적합니다.

Stat 명령어

stat PCG로 PCG 실행 시간, 포인트 수, 메모리 사용을 실시간 모니터링합니다.

에디터 미리보기

Editor Viewport Generation Source로 에디터에서 런타임 동작을 미리 확인할 수 있습니다.

런타임 생성 성능 주의

런타임 PCG 생성은 게임 프레임에 직접 영향을 미칩니다. 한 프레임에 너무 많은 셀이 생성되면 프레임 드롭이 발생합니다. Generation Budget을 설정하여 프레임당 최대 생성량을 제한하고, 무거운 노드(World Ray Hit Query 등)는 런타임 그래프에서 가급적 피하세요.

SUMMARY

핵심 요약

  • Runtime Generation은 플레이어 근처에서 동적으로 콘텐츠를 생성하고 멀어지면 정리한다
  • Generation Source는 Player Controller, WP Streaming, 커스텀 Component 등이 있다
  • Frustum Culling으로 시야 밖 생성을 건너뛰어 약 50% 성능을 절약할 수 있다
  • Cleanup Radius = Generation Radius x Multiplier로 Hysteresis를 구현하여 깜빡임을 방지한다
  • 권장 패턴: 대형/중형은 사전 생성(On Load), 소형 디테일만 Runtime으로 동적 생성한다
  • pcg.Debug.DrawCells, stat PCG, LogPCG로 런타임 동작을 디버깅한다
PRACTICE

도전 과제

배운 내용을 직접 실습해보세요

실습 1: 런타임 PCG 생성 테스트

GenerateAtRuntime을 활성화하고 게임 플레이 중 PCG가 실행되는 것을 확인하세요. 블루프린트에서 Generate 함수를 호출하여 버튼 입력 시 환경이 생성되는 인터랙션을 만드세요.

실습 2: Seed 기반 월드 변형

런타임에서 PCG Seed를 변경하여 동일한 그래프로 다른 월드 변형을 생성하세요. 매번 다른 레이아웃이 나오는 로그라이크 스타일 레벨 생성을 구현하세요.

심화 과제: 스트리밍 기반 런타임 PCG

플레이어 주변만 런타임으로 PCG를 생성하고, 떠나면 해제하는 스트리밍 시스템을 C++로 구현하세요. 시각적 팝인 방지를 위한 페이드 처리와 비동기 생성을 추가하세요.