PART 6 - 강의 3/4
흔한 문제 해결
World Partition 개발 시 자주 발생하는 문제와 해결책
01
에디터 vs 패키지 빌드 차이
개발 환경과 배포 환경의 차이
문제: 에디터에서는 작동하지만 패키지에서 실패
증상:
- 레벨이 패키지 빌드에서 로드되지 않음
- PIE에서는 정상, Standalone에서 문제
원인과 해결책:
1. HLOD 빌드 누락
문제: HLOD가 빌드되지 않아 원거리 렌더링 실패
해결: Build > Build HLODs 실행
또는 WorldPartitionHLODsBuilder 커맨드렛
2. 메모리 부족
문제: 패키지 빌드 시 64GB+ 메모리 소비
해결: 그리드 셀 크기 조정, HLOD 레이어 최적화
3. Level Instance 로드 타이밍
문제: Level Instance가 PIE에서는 즉시 로드되지만
패키지에서는 UpdateStreamingState 필요
해결: 명시적 로드 요청 및 대기
| 항목 | 에디터/PIE | 패키지 빌드 |
|---|---|---|
| OFPA | 개별 파일에서 직접 스트리밍 | 레벨 파일에 임베드됨 |
| Level Instance | 즉시 로드 | UpdateStreamingState 필요 |
| HLOD | 때때로 불안정 | 일반적으로 안정적 |
02
모든 셀이 항상 로드됨
Is Spatially Loaded가 작동하지 않는 경우
문제: 스트리밍이 작동하지 않음
증상:
- Is Spatially Loaded 설정에도 불구하고 모든 셀 로드
- 메모리 사용량이 예상보다 높음
진단:
1. wp 디버그 콘솔 명령 실행
wp.Runtime.ToggleDrawRuntimeHash2D
2. 그리드 경계에 배치된 액터 확인
- 경계에 걸친 액터는 여러 셀에 포함됨
해결책:
1. 액터 위치 확인
- 그리드 셀 경계에 걸친 액터는 항상 로드됨
- 액터를 셀 내부로 이동
2. 하드 레퍼런스 체크
- 맵 전체에 걸친 하드 레퍼런스는 거대한 셀 생성
- Soft References 사용
3. CVar 확인
wp.Runtime.RuntimeSpatialHashPlaceSmallActorsUsingLocation 1
거대 셀 원인
액터 간 Hard Reference가 있으면 같은 셀에 배치됩니다. 멀리 떨어진 액터 간 레퍼런스가 있으면 거대한 셀이 생성되어 스트리밍 효과가 감소합니다.
03
HLOD 스트리밍 문제
HLOD가 PIE에서 불안정한 경우
문제: HLOD가 PIE에서 랜덤하게 스트리밍되지 않음
증상:
- PIE에서 HLOD가 때때로 표시되지 않음
- 원거리에서 빈 공간이 보임
원인:
- 특정 레벨이 PIE에서 HLOD를 스트리밍하지 않는 버그 (버전별)
해결책:
1. 패키지 빌드 테스트
- PIE 대신 Standalone으로 테스트
- 일반적으로 패키지 빌드에서는 정상 동작
2. HLOD 리빌드
- Build > Build HLODs
- 또는 전체 리빌드 (Delete → Setup → Build)
3. 엔진 버전 업그레이드
- HLOD 관련 버그는 지속적으로 수정됨
4. 디버그 확인
wp.Runtime.ToggleHLODDebug
04
Data Layer 상태 변경 실패
SetDataLayerRuntimeState가 작동하지 않음
C++ - Data Layer 문제 진단
// 증상: SetDataLayerRuntimeState 호출 후 변화 없음
// 진단 코드
void DiagnoseDataLayerIssue(UDataLayerAsset* DataLayer)
{
if (!DataLayer)
{
UE_LOG(LogTemp, Error, TEXT("DataLayer is null!"));
return;
}
UWorld* World = GetWorld();
if (!World)
{
UE_LOG(LogTemp, Error, TEXT("World is null!"));
return;
}
UDataLayerManager* Manager = UDataLayerManager::GetDataLayerManager(World);
if (!Manager)
{
UE_LOG(LogTemp, Error, TEXT("DataLayerManager not found!"));
return;
}
EDataLayerRuntimeState CurrentState =
Manager->GetDataLayerEffectiveRuntimeState(DataLayer);
EDataLayerRuntimeState TargetState =
Manager->GetDataLayerRuntimeState(DataLayer);
UE_LOG(LogTemp, Log,
TEXT("DataLayer '%s': Current=%d, Target=%d"),
*DataLayer->GetName(),
(int32)CurrentState,
(int32)TargetState);
}
// 체크리스트:
// 1. Runtime Data Layer인지 확인 (Editor가 아닌)
// 2. World Partition이 활성화되어 있는지 확인
// 3. HasAuthority() 체크 (네트워크 게임)
흔한 실수
Editor Data Layer에 SetDataLayerRuntimeState 호출. Runtime 타입으로 변경 필요.
해결책
Data Layer Asset에서 Type을 Runtime으로 설정하고 초기 상태 확인.
05
네트워크 동기화 문제
서버-클라이언트 스트리밍 불일치
문제: 서버와 클라이언트의 셀 로드 상태 불일치
증상:
- 서버에서 셀이 로드되었지만 클라이언트에서는 아직 로드 안 됨
- 액터 리플리케이션 실패
- 텔레포트 시 콘텐츠 누락
해결책:
1. Net Relevancy 설정
- IsNetRelevantFor() 오버라이드
- 클라이언트 셀 로드 상태 확인
2. 프리로딩 전략
- 텔레포트 전 타겟 위치 미리 로드
- 스트리밍 완료 대기 후 이동
3. Server Streaming 확인
wp.Runtime.EnableServerStreaming 1
4. Data Layer 동기화
- 서버에서만 Data Layer 상태 변경
- HasAuthority() 체크
SUMMARY
핵심 요약
- 에디터 vs 패키지: HLOD 빌드 확인, Level Instance 로드 타이밍 차이
- 모든 셀 로드: 셀 경계 액터, Hard Reference 체크
- HLOD 불안정: 패키지 빌드 테스트, 리빌드, 엔진 업그레이드
- Data Layer 실패: Runtime 타입 확인, Manager 존재 확인
- 네트워크 문제: Net Relevancy, 프리로딩, Server Streaming
PRACTICE
도전 과제
배운 내용을 직접 실습해보세요
실습 1: 셀 경계 팝인 문제 해결
플레이어 이동 시 셀 경계에서 발생하는 액터 팝인(pop-in) 문제를 재현하고 해결하세요. LoadingRange 조절, HLOD 전환 거리 조정, 스트리밍 소스 Shape 확장 등의 해결 방법을 시도합니다.
실습 2: 크로스 셀 레퍼런스 문제 해결
서로 다른 셀의 액터 간 하드 레퍼런스로 인한 문제(불필요한 셀 동시 로드)를 진단하고 해결하세요. Reference Viewer에서 의존성을 분석하고, 소프트 레퍼런스나 인터페이스로 대체합니다.
심화 과제
스트리밍 실패, HLOD 빌드 오류, Data Layer 충돌, 에디터 크래시 등 주요 문제에 대한 진단 및 해결 체크리스트를 작성하고, 자동 진단 스크립트(에디터 유틸리티)를 구현하세요.