Significance Manager
플레이어 중요도에 따라 동적으로 업데이트 빈도를 조절합니다
Significance Manager 개요
중요도 기반 리소스 배분
Significance Manager는 플레이어의 중요도에 따라 액터를 버킷으로 분류하고, 이 우선순위를 다양한 게임 요소에 적용합니다.
Fortnite 사례
매 프레임 업데이트
고품질 애니메이션
전체 물리 시뮬레이션
10Hz 업데이트
중간 LOD
간소화된 애니메이션
2Hz 업데이트
최저 LOD
물리 비활성화
플레이어가 인지하지 못하는 곳에 연산 자원을 낭비하지 마세요. 멀리 있거나 보이지 않는 오브젝트는 덜 자주, 덜 정밀하게 업데이트해도 됩니다.
중요도 점수 산출
다양한 산출 방식
중요도 산출 모드
| 모드 | 설명 | 사용 사례 |
|---|---|---|
| Render | 렌더링 여부 기반 | 시각적 요소 |
| Distance | 거리 기반 | 일반적인 게임 오브젝트 |
| Angle | 뷰 각도 기반 | 시야 내 오브젝트 우선 |
| Screen Space Ratio | 화면 비율 기반 | 큰 오브젝트 우선 |
| Weighted Distance + Render | 가중치 적용 복합 | 정밀한 제어 필요 시 |
C++ 구현
Significance Manager 등록 및 활용
#include "SignificanceManager.h"
void AMyActor::BeginPlay()
{
Super::BeginPlay();
// Significance Manager 가져오기
USignificanceManager* SignificanceManager =
USignificanceManager::Get(GetWorld());
if (SignificanceManager)
{
// 중요도 계산 함수와 콜백 등록
SignificanceManager->RegisterObject(
this,
FName("MyActorTag"),
// 중요도 계산 람다
[this](USignificanceManager::FManagedObjectInfo* ObjectInfo,
const FTransform& ViewPoint,
float Time,
const TOptional<bool>& bIsVisible) -> float
{
// 거리 기반 중요도 계산
float Distance = FVector::Dist(
GetActorLocation(),
ViewPoint.GetLocation()
);
return FMath::Max(0.0f, 1.0f - (Distance / MaxSignificanceDistance));
},
// 중요도 변경 콜백
[this](USignificanceManager::FManagedObjectInfo* ObjectInfo,
float OldSignificance,
float NewSignificance)
{
OnSignificanceChanged(OldSignificance, NewSignificance);
}
);
}
}
void AMyActor::OnSignificanceChanged(float OldSignificance, float NewSignificance)
{
if (NewSignificance < 0.3f)
{
// 낮은 중요도: 느린 틱, 저품질
SetActorTickInterval(0.5f);
SetLODLevel(2);
}
else if (NewSignificance < 0.7f)
{
// 중간 중요도
SetActorTickInterval(0.1f);
SetLODLevel(1);
}
else
{
// 높은 중요도: 최대 틱, 고품질
SetActorTickInterval(0.0f); // 매 프레임
SetLODLevel(0);
}
}
void AMyActor::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
USignificanceManager* SignificanceManager =
USignificanceManager::Get(GetWorld());
if (SignificanceManager)
{
SignificanceManager->UnregisterObject(this);
}
Super::EndPlay(EndPlayReason);
}
활용 범위
Significance를 적용할 수 있는 영역
⏱️ Tick Interval
중요도에 따라 업데이트 빈도 조절
🎨 LOD 레벨
낮은 중요도 = 낮은 디테일
🦴 애니메이션
본 업데이트 빈도, IK 활성화
🔊 오디오
사운드 재생 우선순위, 컬링
✨ 파티클
이펙트 복잡도, 스폰 레이트
🧠 AI
의사결정 빈도, 경로 탐색 정밀도
Significance Manager의 효과를 극대화하려면 모든 동적 시스템에 적용하세요. 특히 NPC, 파티클, 오디오 같은 비용이 높은 시스템에서 큰 효과를 볼 수 있습니다.
핵심 요약
- Significance Manager: 플레이어 중요도에 따라 리소스 배분
- 중요도 산출: 거리, 각도, 가시성, 화면 비율 등 다양한 방식
- RegisterObject로 등록, UnregisterObject로 해제
- 콜백에서 Tick Interval, LOD, 애니메이션 품질 등 동적 조절
- Fortnite 사례: 보이지 않는 플레이어는 낮은 우선순위로 연산 절약
다음 강의에서는 Object Pooling 패턴으로 스폰/파괴 비용을 최소화하는 방법을 다룹니다.
도전 과제
배운 내용을 직접 실습해보세요
USignificanceManager에 커스텀 Managed Object를 등록하세요. PostSignificanceFunction에서 Significance 값에 따라 Actor의 Tick 주기와 애니메이션 LOD를 동적으로 변경합니다.
카메라와의 거리를 기반으로 0.0~1.0 사이의 Significance 값을 반환하는 함수를 구현하세요. 100개의 NPC에 적용하여 stat game에서 Tick 비용 감소를 확인합니다.
거리, 화면 차지 비율, 게임플레이 중요도(보스 vs 일반 몬스터)를 복합적으로 고려하는 커스텀 Significance 시스템을 구현하세요. 각 요소의 가중치를 데이터 에셋으로 관리합니다.