PART 2 · 강의 2/4

Significance Manager

플레이어 중요도에 따라 동적으로 업데이트 빈도를 조절합니다

01

Significance Manager 개요

중요도 기반 리소스 배분

Significance Manager는 플레이어의 중요도에 따라 액터를 버킷으로 분류하고, 이 우선순위를 다양한 게임 요소에 적용합니다.

🎯 Significance Manager 작동 원리
👁️ 가시성
렌더링 여부
+
📏 거리
플레이어와의 거리
📊 중요도 점수
0.0 ~ 1.0
⚙️ 리소스 배분
Tick, LOD, 애니메이션

Fortnite 사례

🎮 Fortnite 중요도 버킷 시스템
🟢 높은 중요도
가까운 플레이어

매 프레임 업데이트
고품질 애니메이션
전체 물리 시뮬레이션

🟡 중간 중요도
보이는 플레이어

10Hz 업데이트
중간 LOD
간소화된 애니메이션

🔴 낮은 중요도
멀거나 안 보이는

2Hz 업데이트
최저 LOD
물리 비활성화

핵심 원칙

플레이어가 인지하지 못하는 곳에 연산 자원을 낭비하지 마세요. 멀리 있거나 보이지 않는 오브젝트는 덜 자주, 덜 정밀하게 업데이트해도 됩니다.

02

중요도 점수 산출

다양한 산출 방식

중요도 산출 모드

모드 설명 사용 사례
Render 렌더링 여부 기반 시각적 요소
Distance 거리 기반 일반적인 게임 오브젝트
Angle 뷰 각도 기반 시야 내 오브젝트 우선
Screen Space Ratio 화면 비율 기반 큰 오브젝트 우선
Weighted Distance + Render 가중치 적용 복합 정밀한 제어 필요 시
03

C++ 구현

Significance Manager 등록 및 활용

🔄 Significance Manager 등록 프로세스
1
BeginPlay
RegisterObject 호출
2
계산 함수
중요도 점수 산출
3
콜백
변경 시 반응
4
EndPlay
UnregisterObject
⭐ 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); } }
EndPlay에서 해제
코드 보기
void AMyActor::EndPlay(const EEndPlayReason::Type EndPlayReason) { USignificanceManager* SignificanceManager = USignificanceManager::Get(GetWorld()); if (SignificanceManager) { SignificanceManager->UnregisterObject(this); } Super::EndPlay(EndPlayReason); }
04

활용 범위

Significance를 적용할 수 있는 영역

🎯 Significance 적용 영역

⏱️ Tick Interval

중요도에 따라 업데이트 빈도 조절

🎨 LOD 레벨

낮은 중요도 = 낮은 디테일

🦴 애니메이션

본 업데이트 빈도, IK 활성화

🔊 오디오

사운드 재생 우선순위, 컬링

✨ 파티클

이펙트 복잡도, 스폰 레이트

🧠 AI

의사결정 빈도, 경로 탐색 정밀도

실전 팁

Significance Manager의 효과를 극대화하려면 모든 동적 시스템에 적용하세요. 특히 NPC, 파티클, 오디오 같은 비용이 높은 시스템에서 큰 효과를 볼 수 있습니다.

SUMMARY

핵심 요약

  • Significance Manager: 플레이어 중요도에 따라 리소스 배분
  • 중요도 산출: 거리, 각도, 가시성, 화면 비율 등 다양한 방식
  • RegisterObject로 등록, UnregisterObject로 해제
  • 콜백에서 Tick Interval, LOD, 애니메이션 품질 등 동적 조절
  • Fortnite 사례: 보이지 않는 플레이어는 낮은 우선순위로 연산 절약
다음 단계

다음 강의에서는 Object Pooling 패턴으로 스폰/파괴 비용을 최소화하는 방법을 다룹니다.

PRACTICE

도전 과제

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

실습 1: Significance Manager 기본 설정

USignificanceManager에 커스텀 Managed Object를 등록하세요. PostSignificanceFunction에서 Significance 값에 따라 Actor의 Tick 주기와 애니메이션 LOD를 동적으로 변경합니다.

실습 2: 거리 기반 Significance 함수

카메라와의 거리를 기반으로 0.0~1.0 사이의 Significance 값을 반환하는 함수를 구현하세요. 100개의 NPC에 적용하여 stat game에서 Tick 비용 감소를 확인합니다.

심화 과제

거리, 화면 차지 비율, 게임플레이 중요도(보스 vs 일반 몬스터)를 복합적으로 고려하는 커스텀 Significance 시스템을 구현하세요. 각 요소의 가중치를 데이터 에셋으로 관리합니다.