icon안동민 개발노트

환경 요소의 성능 분석


 언리얼 엔진에서 게임 환경의 성능을 분석하는 것은 최적화된 게임 경험을 제공하는 데 핵심적입니다.

 이 절에서는 다양한 성능 분석 도구와 기법을 살펴보겠습니다.

프로파일링 도구 사용법

 언리얼 인사이트 활용

  1. 'Window > Developer Tools > Session Frontend' 열기
  2. 'Unreal Insights' 탭 선택
  3. 'Start New Session' 클릭하여 프로파일링 시작

 코드 기반 프로파일링

DECLARE_CYCLE_STAT(TEXT("Environment Update"), STAT_EnvironmentUpdate, STATGROUP_Game);
 
void AEnvironmentManager::UpdateEnvironment(float DeltaTime)
{
    SCOPE_CYCLE_COUNTER(STAT_EnvironmentUpdate);
 
    // 환경 업데이트 로직
}

성능 통계 해석 방법

 통계 명령어 활용

UCLASS()
class APerformanceAnalyzer : public AActor
{
    GENERATED_BODY()
 
public:
    UFUNCTION(Exec)
    void AnalyzePerformance();
};
 
void APerformanceAnalyzer::AnalyzePerformance()
{
    GEngine->Exec(GetWorld(), TEXT("Stat Unit"));
    GEngine->Exec(GetWorld(), TEXT("Stat FPS"));
    GEngine->Exec(GetWorld(), TEXT("Stat Game"));
}

주요 성능 지표 모니터링

 FPS, 드로우 콜, 메모리 사용량 모니터링

UCLASS()
class UPerformanceMonitor : public UObject
{
    GENERATED_BODY()
 
public:
    void Update();
 
private:
    float GetFPS();
    int32 GetDrawCalls();
    float GetMemoryUsageMB();
};
 
void UPerformanceMonitor::Update()
{
    float CurrentFPS = GetFPS();
    int32 DrawCalls = GetDrawCalls();
    float MemoryUsage = GetMemoryUsageMB();
 
    UE_LOG(LogPerformance, Log, TEXT("FPS: %.2f, Draw Calls: %d, Memory: %.2f MB"), CurrentFPS, DrawCalls, MemoryUsage);
}

렌더링 병목 지점 식별

 GPU 프로파일러 사용

  1. 콘솔에서 Stat GPU 명령 실행
  2. 프레임 시간 분포 분석
  3. 가장 비용이 큰 렌더링 작업 식별

 셰이더 복잡도 분석

UFUNCTION(Exec)
void AnalyzeShaderComplexity()
{
    GEngine->Exec(GetWorld(), TEXT("ViewMode ShaderComplexity"));
}

LOD 시스템 효과 분석

 LOD 통계 시각화

UCLASS()
class ALODAnalyzer : public AActor
{
    GENERATED_BODY()
 
public:
    UFUNCTION(Exec)
    void VisualizeLODLevels();
 
private:
    void DrawLODInfo(UStaticMeshComponent* MeshComponent);
};
 
void ALODAnalyzer::VisualizeLODLevels()
{
    TArray<AActor*> StaticMeshActors;
    UGameplayStatics::GetAllActorsOfClass(GetWorld(), AStaticMeshActor::StaticClass(), StaticMeshActors);
 
    for (AActor* Actor : StaticMeshActors)
    {
        UStaticMeshComponent* MeshComponent = Cast<AStaticMeshActor>(Actor)->GetStaticMeshComponent();
        DrawLODInfo(MeshComponent);
    }
}

물리 시뮬레이션의 성능 영향 평가

 물리 프로파일링

UFUNCTION(Exec)
void ProfilePhysics()
{
    GEngine->Exec(GetWorld(), TEXT("P.VisualizePhysicsCreep 1"));
    GEngine->Exec(GetWorld(), TEXT("Stat PhysicsVerbose"));
}

오픈 월드 환경에서의 성능 분석 전략

 섹터 기반 분석

UCLASS()
class AWorldPerformanceAnalyzer : public AActor
{
    GENERATED_BODY()
 
public:
    UFUNCTION(Exec)
    void AnalyzeWorldSector(FVector Location, float Radius);
 
private:
    void ProfileSectorPerformance(FVector Center, float Radius);
};
 
void AWorldPerformanceAnalyzer::AnalyzeWorldSector(FVector Location, float Radius)
{
    ProfileSectorPerformance(Location, Radius);
    // 섹터 내 오브젝트 수, 메모리 사용량, 렌더링 비용 등 분석
}

다양한 하드웨어 환경에서의 성능 테스트

 자동화된 성능 테스트 구현

UCLASS()
class UPerformanceTestSuite : public UAutomationTest
{
    GENERATED_BODY()
 
public:
    UPerformanceTestSuite(const FObjectInitializer& ObjectInitializer);
 
    virtual bool RunTest(const FString& Parameters) override;
 
private:
    void SetupTestEnvironment(EHardwareClass HardwareClass);
    void RunPerformanceTests();
    void LogResults();
};
 
bool UPerformanceTestSuite::RunTest(const FString& Parameters)
{
    TArray<EHardwareClass> HardwareClasses = { EHardwareClass::Low, EHardwareClass::Medium, EHardwareClass::High };
 
    for (EHardwareClass HardwareClass : HardwareClasses)
    {
        SetupTestEnvironment(HardwareClass);
        RunPerformanceTests();
        LogResults();
    }
 
    return true;
}

성능 데이터 기반 최적화 우선순위 결정

 성능 병목 분석기

UCLASS()
class UPerformanceBottleneckAnalyzer : public UObject
{
    GENERATED_BODY()
 
public:
    void AnalyzeBottlenecks();
 
private:
    TArray<FString> IdentifyTopBottlenecks();
    void SuggestOptimizations(const TArray<FString>& Bottlenecks);
};
 
void UPerformanceBottleneckAnalyzer::AnalyzeBottlenecks()
{
    TArray<FString> TopBottlenecks = IdentifyTopBottlenecks();
    SuggestOptimizations(TopBottlenecks);
}

성능 분석 결과가 개발에 미치는 영향

 1. 레벨 디자인 조정

  • 성능 병목 지점을 피해 레벨 레이아웃 재구성
  • 고성능 요구 구역과 저성능 요구 구역의 균형 조정

 2. 아트 파이프라인 최적화

  • 성능에 큰 영향을 미치는 에셋 식별 및 최적화
  • LOD 전략 재검토 및 개선

 3. 게임플레이 메커닉 재고

  • 성능 집약적 기능의 대안 탐색
  • 성능과 게임플레이 간의 최적의 균형점 모색

 4. 기술적 부채 관리

  • 성능 문제의 근본 원인 파악 및 해결 계획 수립
  • 장기적 성능 개선을 위한 리팩토링 계획 수립

 5. 타겟 플랫폼 전략

  • 다양한 하드웨어 사양에 대한 성능 분석을 바탕으로 타겟 플랫폼 조정
  • 최소 사양 요구사항 재정의

 환경 요소의 성능 분석은 게임 개발 과정에서 매우 중요한 역할을 합니다.

 언리얼 인사이트, 내장 프로파일링 도구, 그리고 사용자 정의 분석 도구를 활용하여 게임 환경의 다양한 측면에서 성능을 세밀하게 분석할 수 있습니다.

 프로파일링 도구는 게임의 전반적인 성능 상태를 파악하는 데 도움을 줍니다.

 코드 기반 프로파일링을 통해 특정 기능이나 시스템의 성능을 정확히 측정할 수 있으며, 이는 최적화 작업의 기초가 됩니다.

 성능 통계 해석은 게임의 전반적인 건강 상태를 판단하는 데 중요합니다.

 FPS, 드로우 콜, 메모리 사용량 등의 주요 지표를 지속적으로 모니터링함으로써 성능 저하의 조기 징후를 포착하고 대응할 수 있습니다.

 렌더링 병목 지점 식별은 그래픽 성능 최적화의 핵심입니다.

 GPU 프로파일러와 셰이더 복잡도 분석을 통해 가장 비용이 큰 렌더링 작업을 찾아내고 최적화할 수 있습니다.

 자동화된 성능 테스트 스위트를 구축하여 다양한 하드웨어 구성에서의 성능을 효율적으로 검증할 수 있습니다.

 성능 데이터를 바탕으로 한 최적화 우선순위 결정은 개발 리소스를 효율적으로 활용하는 데 도움이 됩니다.

 가장 큰 영향을 미치는 병목 지점을 식별하고 이에 집중함으로써 최대의 성능 개선 효과를 얻을 수 있습니다.