icon안동민 개발노트

크로스 플랫폼 호환성 기본 이해


 나이아가라 파티클 시스템의 크로스 플랫폼 개발은 다양한 하드웨어와 소프트웨어 환경에서 일관된 시각적 품질과 성능을 제공하는 것을 목표로 합니다.

 이 절에서는 크로스 플랫폼 개발의 주요 고려사항과 최적화 전략을 살펴보겠습니다.

플랫폼별 나이아가라 시스템 동작 차이

 PC vs 콘솔 vs 모바일

  • PC : 높은 연산 능력, 다양한 하드웨어 스펙
  • 콘솔 : 일관된 하드웨어, 최적화된 성능
  • 모바일 : 제한된 연산 능력, 배터리 소모 고려 필요

 플랫폼별 성능 고려사항

[System Settings]
Max Particles:
  PC: 10000
  Console: 5000
  Mobile: 1000
 
GPU Simulation:
  PC: Enabled
  Console: Enabled
  Mobile: Disabled (일부 고성능 기기 제외)

호환성 있는 파티클 시스템 설계

 스케일러블 파라미터 사용

UPROPERTY(EditAnywhere, Category = "Performance")
FRuntimeFloatCurve ParticleCountScaleCurve;
 
float ScaleFactor = GetScaleFactorForPlatform();
int32 ActualParticleCount = FMath::FloorToInt(ParticleCountScaleCurve.Eval(ScaleFactor));

 조건부 기능 활성화

[Emitter Update]
if (PlatformSupportsGPUSimulation())
{
    EnableGPUSimulation();
}
else
{
    EnableCPUSimulation();
}

플랫폼별 렌더링 파이프라인 최적화

 모바일용 간소화된 셰이더

// 모바일용 간소화된 파티클 셰이더
Shader "Mobile/SimpleParticle"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags {"Queue"="Transparent" "RenderType"="Transparent"}
        LOD 100
 
        CGPROGRAM
        #pragma surface surf Lambert alpha
 
        sampler2D _MainTex;
 
        struct Input
        {
            float2 uv_MainTex;
            fixed4 color : COLOR;
        };
 
        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * IN.color;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
}

 플랫폼별 렌더링 설정

[Renderer Settings]
if (Platform == Mobile)
{
    Uses Soft Particles = false;
    Max Draw Count = 50;
}
else
{
    Uses Soft Particles = true;
    Max Draw Count = 200;
}

LOD (Level of Detail) 시스템 구현

 거리 기반 LOD

[LOD Settings]
LOD 0 (0-500 units): Full quality
LOD 1 (500-1000 units): 75% particles, simplified shaders
LOD 2 (1000+ units): 50% particles, basic effects

 성능 기반 동적 LOD

float GetDynamicLODLevel()
{
    float CurrentFPS = GetCurrentFPS();
    float TargetFPS = GetTargetFPSForPlatform();
    
    return FMath::Clamp((TargetFPS - CurrentFPS) / TargetFPS, 0.0f, 1.0f);
}
 
// 파티클 시스템 업데이트에서
float LODFactor = GetDynamicLODLevel();
int32 ParticleCount = FMath::Lerp(MaxParticles, MinParticles, LODFactor);

다양한 하드웨어 스펙 대응

 자동 성능 감지

void AdjustSettingsForHardware()
{
    FString PlatformName = UGameplayStatics::GetPlatformName();
    int32 SystemMemory = FPlatformMemory::GetPhysicalGBRam();
    bool bIsHighEndGPU = DetectHighEndGPU();
 
    if (PlatformName == "Android" || PlatformName == "IOS")
    {
        if (SystemMemory < 4)
        {
            SetLowQualitySettings();
        }
        else if (bIsHighEndGPU)
        {
            SetHighQualitySettings();
        }
        else
        {
            SetMediumQualitySettings();
        }
    }
    // PC, 콘솔 등 다른 플랫폼에 대한 처리
}

 사용자 정의 품질 설정

[Quality Settings]
Low: Max Particles = 1000, No Soft Particles, Simple Shaders
Medium: Max Particles = 5000, Soft Particles, Standard Shaders
High: Max Particles = 10000, Soft Particles, Complex Shaders with Distortion

크로스 플랫폼 개발 시 일반적인 문제와 해결 방안

  1. 텍스처 압축 포맷 차이
  • 해결 : 플랫폼별 적절한 압축 포맷 사용 (예 : DXT for PC, ASTC for Mobile)
  1. 셰이더 모델 호환성
  • 해결 : 플랫폼별 셰이더 변형 제공, 폴백 셰이더 구현
  1. 메모리 제한
  • 해결 : 메모리 풀링, 동적 리소스 로딩/언로딩
  1. 입력 처리 차이
  • 해결 : 추상화된 입력 시스템 구현

효과적인 테스트 및 품질 관리

 자동화된 성능 테스트

void RunPerformanceTest()
{
    for (int32 i = 0; i < TestScenarios.Num(); ++i)
    {
        FTestScenario& Scenario = TestScenarios[i];
        float AverageFPS = MeasureAverageFPS(Scenario, 30.0f); // 30초 동안 측정
        
        FString Result = FString::Printf(TEXT("Scenario %d: Avg FPS = %.2f"), i, AverageFPS);
        UE_LOG(LogNiagaraPerformance, Log, TEXT("%s"), *Result);
    }
}

 시각적 일관성 체크

  • 각 플랫폼에서 스크린샷 캡처 및 비교 도구 활용
  • 주요 시나리오에 대한 비디오 캡처 및 분석

크로스 플랫폼 개발 시 주의사항 및 팁

  1. 최소 사양 기기에서 먼저 개발 및 테스트
  2. 플랫폼별 특화 기능은 #ifdef 등을 사용하여 조건부 컴파일
  3. 공통 코드 베이스 유지, 플랫폼별 차이는 최소화
  4. 지속적인 프로파일링 및 최적화 수행
  5. 플랫폼별 인증 요구사항 숙지 및 준수

실제 적용 예시 : 폭발 효과의 크로스 플랫폼 최적화

  1. 기본 설정
NS_Explosion:
  Emitters:
    - NE_Core
    - NE_Sparks
    - NE_Smoke
    - NE_Debris
  1. 플랫폼별 조정
void AdjustExplosionForPlatform()
{
    switch(GetPlatform())
    {
        case PLATFORM_PC:
            SetEmitterSettings(NE_Core, 1000, true);
            SetEmitterSettings(NE_Sparks, 500, true);
            SetEmitterSettings(NE_Smoke, 200, true);
            SetEmitterSettings(NE_Debris, 300, true);
            EnablePostProcessing(true);
            break;
        
        case PLATFORM_CONSOLE:
            SetEmitterSettings(NE_Core, 800, true);
            SetEmitterSettings(NE_Sparks, 400, true);
            SetEmitterSettings(NE_Smoke, 150, true);
            SetEmitterSettings(NE_Debris, 200, true);
            EnablePostProcessing(true);
            break;
        
        case PLATFORM_MOBILE:
            SetEmitterSettings(NE_Core, 500, false);
            SetEmitterSettings(NE_Sparks, 200, false);
            SetEmitterSettings(NE_Smoke, 100, false);
            SetEmitterSettings(NE_Debris, 0, false); // 비활성화
            EnablePostProcessing(false);
            break;
    }
}
 
void SetEmitterSettings(UNiagaraEmitter* Emitter, int32 MaxParticles, bool UseComplexShaders)
{
    if (Emitter)
    {
        Emitter->SetMaxParticles(MaxParticles);
        Emitter->SetMaterial(UseComplexShaders ? ComplexMaterial : SimpleMaterial);
    }
}
  1. LOD 시스템 적용
[LOD Settings]
LOD 0 (0-500 units): Full effect
LOD 1 (500-1000 units):
  - 75% particle count
  - Disable NE_Debris
LOD 2 (1000+ units):
  - 50% particle count
  - Disable NE_Debris and NE_Smoke
  1. 성능 모니터링 및 동적 조정
void UpdateExplosionPerformance()
{
    float CurrentFPS = GetCurrentFPS();
    float TargetFPS = GetTargetFPSForPlatform();
    
    if (CurrentFPS < TargetFPS * 0.9f) // 성능이 목표의 90% 미만일 때
    {
        ReduceParticleCount(0.1f); // 파티클 수 10% 감소
        SimplifyShaders();
    }
}

 이러한 크로스 플랫폼 접근 방식을 통해 나이아가라 파티클 시스템을 다양한 플랫폼에서 효과적으로 구현할 수 있습니다. 플랫폼별 특성을 고려한 최적화, 스케일러블한 설계, 그리고 지속적인 테스트와 모니터링이 핵심입니다. 개발 초기 단계부터 크로스 플랫폼 호환성을 고려하면, 후반 작업에서의 대규모 수정을 방지하고 일관된 사용자 경험을 제공할 수 있습니다. 항상 각 플랫폼의 최신 개발 가이드라인을 참조하고, 타겟 플랫폼에서의 실제 테스트를 통해 최적의 결과를 얻을 수 있도록 노력하세요.