PART 1 - 강의 2/3

Spatial Hash와 그리드 시스템

World Partition의 공간 해싱과 그리드 셀 구조 이해하기

01

UWorldPartitionRuntimeSpatialHash

공간 해싱을 통한 스트리밍 셀 관리

World Partition은 월드를 2D 그리드로 분할하여 관리합니다. UWorldPartitionRuntimeSpatialHash가 공간 해싱을 담당합니다.

C++ - RuntimeSpatialHash // Spatial Hash 개념 설명 // 위치 -> 셀 이름 매핑 함수 // Cook 시: 스트리밍 레벨 생성에 사용 // Runtime 시: 로드할 레벨 결정에 사용 UCLASS() class ENGINE_API UWorldPartitionRuntimeSpatialHash : public UWorldPartitionRuntimeHash { GENERATED_BODY() public: // 특정 위치에 해당하는 스트리밍 셀 조회 void GetStreamingCells(const FVector& Location, float LoadingRange, TArray<const UWorldPartitionRuntimeCell*>& OutCells); // 서버용: 모든 셀 조회 (Dedicated Server) void GetAllStreamingCells(TArray<const UWorldPartitionRuntimeCell*>& OutCells); protected: // 그리드 설정 UPROPERTY(EditAnywhere, Category = "Grid") int32 CellSize = 12800; // 128m 기본값 UPROPERTY(EditAnywhere, Category = "Grid") int32 LoadingRange = 25600; // 256m 기본값 };
Spatial Hash 작동 원리

위치를 입력받아 해당 위치가 속한 셀 이름을 반환합니다. 이 매핑은 쿡 시 스트리밍 레벨을 생성하고, 런타임에서 로드할 셀을 결정하는 데 사용됩니다.

02

LH Grid (Location Hash Grid)

현재 기본 그리드 시스템

현재 기본 그리드인 LH Grid는 액터를 정규 그리드에 배치하되, 셀이 너무 크거나 작으면 경계를 조정합니다.

C++ - 그리드 셀 경계 조정 (개념적) // 그리드 셀 경계 조정 로직 (개념적 설명) struct FWorldPartitionCell { FBox Bounds; TArray<AActor*> Actors; // 셀이 너무 클 경우 분할 void SubdivideIfNeeded(int32 MaxActorsPerCell) { if (Actors.Num() > MaxActorsPerCell) { // 4개 자식 셀로 분할 SubdivideTo4(); } } // 셀이 너무 작을 경우 병합 void MergeWithNeighborsIfNeeded(int32 MinActorsPerCell) { if (Actors.Num() < MinActorsPerCell) { // 인접 셀과 병합 MergeWithNeighbors(); } } };
파라미터 설명 권장값
CellSize 그리드 셀의 기본 크기 (cm) 12800 (128m)
LoadingRange 셀 로딩 시작 거리 (cm) 25600 (256m)
Priority 로딩 우선순위 0 (기본)
03

그리드 설정 방법

World Settings에서의 런타임 그리드 구성

World Settings 경로 // World Settings > World Partition > Runtime Settings > Grids // 기본 그리드 설정 예시 struct FWorldPartitionRuntimeGrid { FName GridName = "MainGrid"; int32 CellSize = 12800; // 128m (cm 단위) int32 LoadingRange = 25600; // 256m FColor DebugColor = FColor::Green; bool bBlockOnSlowStreaming = false; int32 Priority = 0; // 높을수록 우선 };

다중 그리드 설정 예시

INI - DefaultEngine.ini ; Close Grid - 중요 게임플레이 오브젝트 [/Script/Engine.WorldPartitionRuntimeSpatialHash] GridName=CloseGrid CellSize=6400 LoadingRange=12800 Priority=100 ; Medium Grid - 일반 환경 [/Script/Engine.WorldPartitionRuntimeSpatialHash] GridName=MediumGrid CellSize=12800 LoadingRange=51200 Priority=50 ; Far Grid - 배경 요소 [/Script/Engine.WorldPartitionRuntimeSpatialHash] GridName=FarGrid CellSize=25600 LoadingRange=102400 Priority=10 ; Foliage Grid - 식생 전용 [/Script/Engine.WorldPartitionRuntimeSpatialHash] GridName=FoliageGrid CellSize=12800 LoadingRange=76800 Priority=25
그리드 분리 전략

게임플레이에 중요한 오브젝트는 작은 셀 크기와 짧은 로딩 거리로, 배경 요소는 큰 셀 크기와 긴 로딩 거리로 설정하여 메모리와 성능을 최적화합니다.

04

액터별 그리드 할당

특정 액터를 특정 그리드에 배치

C++ - 액터 그리드 설정 // 액터의 Details 패널에서 설정 // World Partition > Runtime Grid = "FoliageGrid" // 또는 C++에서 설정 UCLASS() class AMyFoliageActor : public AActor { GENERATED_BODY() public: AMyFoliageActor() { // 기본 그리드 설정 (에디터에서 오버라이드 가능) RuntimeGrid = TEXT("FoliageGrid"); } protected: // 런타임 그리드 이름 UPROPERTY(EditAnywhere, Category = "World Partition") FName RuntimeGrid; };

에디터에서 설정

액터 선택 후 Details 패널의 World Partition 카테고리에서 Runtime Grid 프로퍼티를 수정합니다.

C++에서 설정

생성자에서 RuntimeGrid 변수를 설정하면 해당 액터 타입의 기본값으로 적용됩니다.

05

셀 크기 결정 가이드

최적의 CellSize 선택

Cell Size 설정 주의사항

Cell Size는 랜드스케이프 컴포넌트 크기와 일치시키는 것이 좋습니다. 불일치 시 랜드스케이프 스트리밍에서 시각적 아티팩트가 발생할 수 있습니다.

월드 크기 권장 Cell Size 권장 Loading Range
소규모 (4km x 4km) 12800 (128m) 25600 (256m)
중규모 (16km x 16km) 25600 (256m) 51200 (512m)
대규모 (64km x 64km) 51200 (512m) 102400 (1km)
SUMMARY

핵심 요약

  • UWorldPartitionRuntimeSpatialHash가 위치 기반 셀 조회 담당
  • LH Grid는 기본 그리드로, 필요시 셀을 분할/병합
  • CellSize는 랜드스케이프 컴포넌트 크기와 일치 권장
  • 다중 그리드로 오브젝트 타입별 최적화 가능
  • 액터별로 Runtime Grid 프로퍼티로 그리드 할당
PRACTICE

도전 과제

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

실습 1: 그리드 셀 크기 설정 실험

World Partition 설정에서 Runtime Spatial Hash의 CellSize를 12800, 25600, 51200으로 각각 변경하며 PIE에서 셀 로딩 동작을 관찰하세요. wp.Runtime.ToggleDrawRuntimeHash2D 명령어로 그리드를 시각화합니다.

실습 2: Loading Range 조절

RuntimeGrid의 LoadingRange를 다양하게 설정(10000~50000)하며 스트리밍 동작을 비교하세요. 더 넓은 로딩 범위가 메모리 사용량과 로딩 시간에 미치는 영향을 측정합니다.

심화 과제

UWorldPartitionRuntimeSpatialHash를 분석하여 현재 로드된 셀, 대기 중인 셀, 언로드된 셀의 상태를 3D 미니맵으로 시각화하는 에디터 유틸리티를 만드세요.