상시 검증툴
레벨 내 액터들과 컨텐츠 브라우저의 에셋들을 대상으로 상시 검증을 돌려 인게임 리소스가 최대한 프로젝트 규약을 벗어나지 않고 무결하도록 유지하기 위해 상시 돌릴 수 있는 검증툴을 엔진팀에서 제작해주신 경험이 있습니다. 문제가 있는 리소스는 자동 수정이 가능하다면 자동 수정을 제공하고, 작업자의 판단이 필요하다면 수동 수정을 안내하는 수정 기능까지 포함해서 제작해주셨습니다.
어떤 검증 항목들이 있었는지 추후에도 참고하기 위해 프로젝트 고유의 클래스나 기능들에 대한 검증을 제외한 범용적 검증 항목들을 정리해둡니다.
1. 리소스 검증 항목
1.1 공통
- Broken Dependency (에러, 자동수정): 에셋/패키지가 참조하는 대상이 실제로 존재하지 않는 경우.
FDXDependencyCollectionFunctorBase가 의존성을 수집하는 과정에서 끊어진 참조를 발견하면 에러 처리.
- 개인용(Developer) 에셋 참조:
/Game/Developers/ 하위 개인 폴더 에셋이 게임 에셋에서 실제로 참조되고 있으면 에러. 배포 전 반드시 정리 필요.
- NoCooking 에셋 참조 (경고): 쿠킹 대상에서 제외된 에셋(
DirectoriesToNeverCook 등)을 비-에디터전용 액터/에셋이 참조하는 경우 런타임에 해당 에셋이 없을 수 있으므로 경고.
1.2 StaticMesh
- 중복 슬롯 이름 (에러): 머티리얼 슬롯 이름이 겹치면 에러. 이름부터 정리해야 이후 슬롯 관련 검증이 의미 있음.
- 미사용 머티리얼 슬롯 (에러, 자동수정): 어떤 섹션에서도 참조되지 않는 슬롯 → 자동 삭제.
- 미사용 라이트맵 UV 채널 (에러, 자동수정) / 미사용 라이트맵 UV 채널 생성 설정 (에러): 라이트맵에 쓰이지 않는 UV 채널이 남아있거나, 라이트맵 UV 생성 옵션 자체가 잘못 설정된 경우.
- 미사용 UV 채널 (에러): 라이트맵 외 일반 UV 채널 중 아무데도 쓰이지 않는 채널 검출.
- Nanite 미적용 (에러, 삼각형 수 기준 임계값 이상): 삼각형 수가
HIGH_NANITE_TRIANGLES 이상인데 Nanite가 꺼져있으면 에러(단, 얇고 넓은 Plane류 메시는 예외).
- LOD 삼각형 수 역전/미감소 (에러): 상위 LOD가 하위 LOD보다 삼각형이 많거나(LOD 단계에 따라 삼각형 수가 오히려 증가), 삼각형 수가 많은 LOD 사이에서 감소폭이 없는 경우(
CheckMesh_HasLODNoReductionForHighTriangles).
- LOD Screen Size = 0 (에러): 자동계산이 꺼진 상태에서 LOD1 이상의 Screen Size가 0이면 해당 LOD가 절대 적용되지 않으므로 사실상 죽은 LOD → 에러.
- 콜리전 오류 (에러):
bCustomizedCollision=true인데 실제 커스텀 콜리전이 없거나, NoCollision이 아닌데 콜리전 자체가 비어 있는 경우.
- Nanite/Fallback 삼각형 밀도 과다 (에러, 삼각형 수 하한선 이상 대상): 면적당 삼각형 밀도가 임계값을 초과하면 에러. 너무 촘촘한 지오메트리로 인한 성능 저하 방지 목적. 삼각형 수가 적은 메시는 제외.
- Nanite + Translucent 머티리얼 (에러): Nanite 활성 메시에 반투명 블렌드모드 머티리얼 슬롯이 있으면 에러(Nanite는 반투명을 제대로 지원하지 않음).
- NULL 머티리얼 슬롯 (에러, 자동수정): 슬롯에 머티리얼이 비어있으면 에러, 자동수정 시 기본 머티리얼로 채우거나 정리.
1.3 SkeletalMesh
- 미사용 머티리얼 슬롯 (에러, 자동수정): StaticMesh와 동일한 개념.
- LOD0 머티리얼 맵 존재 (경고): 머티리얼 슬롯이 수동으로 편집됐을 가능성을 알려주는 경고(자동 리임포트 대상은 아님).
- 머티리얼 인덱스 오류 (에러):
LOD{n} Section[m]의 Material[k]를 찾을 수 없음 또는 LOD{n} MaterialMap[m]의 Material[k]를 찾을 수 없음 — 메시 리임포트나 머티리얼 재할당 필요.
1.4 Material Instance
- 미사용 오버라이드 텍스처 샘플 (에러, 자동수정): MI에서 오버라이드했지만 부모 머티리얼에서 실제로 안 쓰이는 텍스처 파라미터 → 자동 정리.
- 미사용 텍스처 스트리밍 참조 (에러, 자동수정): 텍스처 스트리밍 목적으로 등록된 참조인데 실제로 사용되지 않는 것 → 정리.
1.5 Blueprint
- NULL 인터페이스 (에러): BP에 붙은 인터페이스 슬롯이 비어있는 경우.
- 같은 GUID, 다른 이름의 인터페이스 (에러): 인터페이스가 리네임되었는데 참조하는 BP 쪽 캐시가 갱신 안 된 경우(
{0}({1}) != {2}({3}) 형태로 출력).
- Blueprint 컴파일 에러 (에러): BP 자체에 컴파일 에러(
BS_Error)가 있는 경우.
1.6 Texture
- 사이즈: 임포트된 사이즈가 수동 설정한 최대 사이즈보다 작음(에러, 자동수정 — 설정값을 낮춤), 에디터 텍스처 사이즈가 디바이스 프로파일(
WindowsNoEditor) 텍스처그룹 최대 사이즈보다 큼(에러).
- POT(2의 거듭제곱): X/Y 크기가 2의 거듭제곱이 아니면 에러(밉맵이 2개 이상인 텍스처만 대상).
- 그룹: 텍스처 네이밍 컨벤션(
_D/_ALBEDO, _N/_NORMAL, _M/_MASK, _H, _EMI_D 등 접미사)과 실제 텍스처 그룹(TEXTUREGROUP_WORLD_D/N/M, TEXTUREGROUP_EMISSIVE 등)이 불일치하면 에러(조건부 자동수정).
- 밉맵: 그룹 규칙상 밉맵이 없어야/있어야 하는데 반대인 경우 에러,
NeverStream 옵션이 켜져 있으면 에러(자동수정), LOD Bias는 반드시 0(자동수정).
- sRGB: Diffuse/Emissive/UI류는 켜짐, Normal/Height/Mask류는 꺼짐이 원칙 — 어긋나면 에러(조건부 자동수정).
- 필터: 디폴트 필터가 아니면 에러(자동수정).
- 압축
- Normalmap인데 DXT5/BC5가 아닌 포맷(조건부 자동수정)
- Normalmap에 불필요한 알파 채널 존재(에러)
- 채널 병합으로 압축 유리한 경우(경고)
- Mask 텍스처에 압축 미적용(에러)
- sRGB를 지원하지 않는 압축포맷 사용(에러)
1.7 Animation
- 30프레임 강제 (에러): 애님시퀀스 프레임레이트가 30fps(혹은 프로젝트 내부적으로 적절하다고 판단되는 fps)가 아니면 에러.
- 몽타주-시퀀스 재생시간 불일치 (에러): 몽타주 슬롯에 들어간 시퀀스의 실제 PlayLength가 몽타주에 설정된 값과 다른 경우(원본 애니메이션이 수정된 후 몽타주가 갱신 안 된 상황) 엔진의
is out-of-sync with the represented AnimationSequence 경고를 근거로 판정.
1.8 Niagara
- Effect Type 없음 (에러): 나이아가라 시스템에 EffectType 미설정.
- 컴파일 실패 (에러): 시스템/이미터 컴파일 오류.
- Stack Issue (에러/경고):
UNiagaraStackEntry::FStackIssue로 노출되는 각종 스택 경고/에러 그대로 리포트.
- 추가로
UNiagaraValidationRule 서브클래스들로 별도 룰 실행:
- FixedBounds 누락
- Audio Data Interface Looping 설정 오류
- Loop Behavior 프로젝트 기준 위반
- Curl Noise Quality
- Require Current Frame Data 불필요 활성화
- Interpolated Spawning 설정
- StaticMeshRenderer 최적화(Distance Field/Collision/UV/LOD)
2. 월드 검증 항목
2.1 공통
- 개인용 에셋 사용 (에러): 월드 내 액터가 Developer 개인 폴더 에셋을 참조.
- NoCooking 에셋 사용 (경고): 리소스 검증과 동일 기준. 쿠킹 대상에서 제외된 에셋(
DirectoriesToNeverCook 등)을 비-에디터전용 액터/에셋이 참조하는 경우 런타임에 해당 에셋이 없을 수 있으므로 경고.
- 스케일 0인 컴포넌트 (에러): 씬 컴포넌트 스케일 성분 중 하나라도 0이면 렌더링/충돌 이슈 유발 가능 → 에러.
- 파티션 액터 디스크립터 불일치: PCG/모듈러 파티션 액터의 이름·레이블·데이터레이어 해시가
FWorldPartitionActorDesc와 어긋나면 에러. 월드파티션 시스템과 실제 액터 상태 불일치를 잡아냄.
2.2 StaticMesh
- Null StaticMesh (경고,
AStaticMeshActor인 경우만 자동수정으로 액터 삭제): 메시 컴포넌트에 메시가 비어있음.
- LOD 강제 셋팅 (에러, 자동수정): 컴포넌트 레벨에서 강제 LOD 지정이 남아있는 경우 → 해제.
- Nanite + Translucent (에러): 리소스 검증과 동일 로직을 컴포넌트 단위로 적용.
- 머티리얼 인덱스 오류 (에러): 메시 리임포트/머티리얼 재할당 필요 안내.
- 중복 슬롯 이름 (에러): 두 슬롯 이름 쌍을 구체적으로 표시(
[{1}] and [{2}]).
2.3 SkeletalMesh
- Null SkeletalMesh (경고,
ASkeletalMeshActor인 경우만 자동수정으로 삭제): 메시 컴포넌트에 메시가 비어있음.
2.4 PackedLevelActor
- Mobility가 Static이 아님 (에러, 자동수정): PackedLevelActor는 성능상 Static이어야 함.
2.5 PCG
- PCGPartitionActor
ActorHiddenInGame이면 안 됨. (에러, 자동수정)
IsEditorOnly이면 안 됨(런타임에 존재해야 함). (에러, 자동수정)
- PCGVolume
GenerationTrigger는 반드시 Generate On Demand(자동 생성 방지). (에러, 자동수정)
IsEditorOnly여야 함(런타임에 남으면 안 됨). (에러, 자동수정)
- Partition 가능 여부에 따라
IsPartitioned 플래그가 맞아야 함. (에러, 자동수정)
- 월드 단위:
PCGWorldActor가 소스컨트롤에 add 안 됐거나 dirty 상태면 에러.
2.6 Foliage
- 레이어 혼재: 같은 월드파티션 셀에 서로 다른 레이어의 폴리지가 섞여 있으면 레이어 병합 필요 에러.
- 스태틱메시 미할당: 폴리지 타입에 메시가 없음 → 삭제하거나 메시 할당 필요.
- HISM NULL 메시 / 타입-HISM 메시 불일치: HISM 컴포넌트의 메시 프로퍼티가 비었거나, 폴리지 타입에 설정된 메시와 실제 HISM이 들고 있는 메시가 다른 경우.
- 컬디스턴스 불일치: 폴리지 액터의 HISM 컬디스턴스 값이 폴리지 타입 설정값과 다름(에러),
InstanceCullDistance=0(경고).
- 그라운드 리맵핑 필요: 컴포넌트와 연결이 끊긴 폴리지 그룹 존재 시 에러 —
foliage.OffGroundThreshold(기본 5) 초과 시 지면과 떨어진 것으로 판정하고, "스냅 상대 높이" 범위 내에서만 자동 재배치.
- 중복 인스턴스: 동일 위치에 같은 인스턴스가 중복 존재.
2.7 CullDistance / Mobility
- World: 월드에
ACullDistanceVolume이 하나도 없으면 에러.
- Cull Distance Volume:
CullDistances/WPO Disable Distances/Nanite Pixel Programmable Distances 목록이 비어있으면 에러 (각 리스트의 값이 0이면 "에러를 피하려면 명시적으로 큰 숫자를 넣어달라"는 에러)
※ Cull Distance Volume은 기능을 확장하여 WPO Disable Distance, Nanite Pixel Programmable Distance도 인스턴스의 크기에 따라 자동 설정되도록 엔진 수정
- ISM/HISM & ISKM:
Current Instance Cull Distance Max가 0이면 에러(수동 설정 또는 컬볼륨 자동설정 확인 요구).
- SM/ISM/HISM & SKM/ISKM:
Current Max Draw Distance, Current WPO Disable Distance, Current Nanite Pixel Programmable Distance 각각 0이면 에러.
※ Cull Distance Volume의 기능을 확장하여 WPO Disable Distance, Nanite Pixel Programmable Distance도 인스턴스의 크기에 따라 자동 설정되도록 엔진 수정
- Mobility: 위 대상 컴포넌트들의 Mobility가 Static이 아니면 에러(자동수정).
2.8 VolumeBrush
- BrushComp 없음 / Brush 없음 / Poly 검증 실패 / Convex 검증 실패 / FPoly-Convex 형태 불일치 / BrushTool-Volume 설정 불일치: 모두 볼륨 브러시의 지오메트리 데이터 정합성 체크로, 재생성이 필요할 수 있음을 안내.
2.9 GameplayTag
- 액터/컴포넌트에 존재하지 않는 게임 태그 (에러, 자동수정): 게임플레이 태그 테이블에서 삭제된 태그가 액터/컴포넌트에 남아있으면 자동 삭제.
2.10 Landscape
- 레이어 개수 초과 (에러): 랜드스케이프 레이어 수가 상한을 넘으면 줄이라는 에러. 레이어 수 상한은 프로젝트에서 규약으로 지정. 보통 4개 정도.
2.11 GroupActor
- 남은 그룹액터 발견 (에러, 자동수정): 에디터 전용
AGroupActor가 레벨에 남아있으면 안 됨 → 자동 언그룹 후 빈 그룹 액터 삭제.
※ 그룹액터를 사용하지 말자는 프로젝트 규약에 따른 규칙
클래스+스태틱메시+트랜스폼 해시가 같은 액터 그룹을 찾고, 속성까지 완전히 동일하면 에러(자동수정 대상), 아래 두 경우는 자동수정 대상에서 제외되고 경고로만 표시:
- 검출된 액터들이 아웃라이너상 서로 다른 폴더에 위치
- (Blockout/일반 StaticMesh 액터에 한해) DataLayerAssets만 다른 경우