icon안동민 개발노트

블루프린트 성능 최적화 기법


 블루프린트는 빠른 프로토타이핑과 개발을 가능하게 하지만, 잘못 사용하면 성능 문제를 일으킬 수 있습니다.

 이 절에서는 블루프린트 시스템의 성능을 최적화하는 다양한 기법과 고려사항을 살펴보겠습니다.

블루프린트 컴파일 옵션 최적화

  1. 블루프린트 nativization 활용
  • 프로젝트 설정에서 'Blueprint Nativization' 활성화
  • 선택된 블루프린트를 C++ 코드로 변환하여 성능 향상
  1. Development / Shipping 빌드 사용
  • 개발 완료 후 최종 빌드에서는 항상 Shipping 구성 사용
Project Settings > Packaging
[ ] Use Pak File
[x] Use IO Store
블루프린트 컴파일 옵션 설정

과도한 Tick 이벤트 사용 줄이기

  1. 필요한 경우에만 Tick 활성화
  • 기본적으로 Tick 비활성화 후 필요 시 활성화
[Event BeginPlay]
    |
[Set Actor Tick Enabled]
Enabled: False
 
[Custom Event: EnableTick]
    |
[Set Actor Tick Enabled]
Enabled: True
  1. Tick Interval 활용
    • 매 프레임 대신 일정 간격으로 Tick 실행
[Set Tick Interval]
Interval: 0.1 // 0.1초마다 Tick
Tick 최적화 노드

효율적인 루프 구현

  1. ForEachLoop 대신 While Loop 사용
  • 대규모 배열 처리 시 더 효율적
[While Loop]
    |
[Array Get]
    |
[Process Element]
    |
[Increment Index]
  1. 불필요한 루프 탈출 조건 추가
  • 조건 충족 시 즉시 루프 종료
[For Loop]
    |
[Branch: Condition Met?]
    |
[Break] <-- True
효율적인 루프 구현

캐싱을 통한 반복적인 계산 줄이기

  1. 자주 사용되는 값 캐싱
  • 변수에 저장하여 재사용
[Event BeginPlay]
    |
[Get Player Character]
    |
[Promote to Variable: PlayerRef]
 
[Custom Event: UsePlayerRef]
    |
[Get PlayerRef]
// PlayerRef 사용
  1. 비용이 높은 함수 결과 캐싱
  • 계산 비용이 높은 함수의 결과를 저장하고 재사용
값 캐싱 예제

대규모 블루프린트 시스템 구조화 및 모듈화

  1. 기능별 모듈 분리
  • 관련 기능을 별도의 블루프린트로 분리
  1. 인터페이스 활용
  • 블루프린트 간 통신에 인터페이스 사용
  1. 이벤트 디스패처 활용
  • 느슨한 결합을 위해 이벤트 기반 통신 구현
[Create Event Dispatcher: OnStateChange]
 
[Call OnStateChange]
    |
[Bind Event to OnStateChange]
모듈화 및 이벤트 디스패처 사용

프로파일링 도구를 사용한 성능 병목 지점 식별

  1. 언리얼 Profiler 사용
  • Window > Developer Tools > Session Frontend > Profiler
  1. Blueprint Profiler 활용
  • 블루프린트 내 성능 문제 지점 식별
  1. Stats 명령어 사용
  • 콘솔에서 stat blueprint 명령어로 실시간 성능 모니터링
프로파일링 도구 사용 예시

메모리 사용 최적화

  1. 불필요한 변수 제거
  • 사용하지 않는 변수 정리
  1. 적절한 변수 타입 사용
  • 필요 이상으로 큰 데이터 타입 지양 (예 : float 대신 half 사용)
  1. 가비지 컬렉션 고려
  • 대량의 객체 생성 및 삭제 시 오브젝트 풀링 고려
[Spawn Actor from Class]
    |
[Add to Object Pool]
 
[Custom Event: ReturnToPool]
    |
[Deactivate Actor]
    |
[Add to Available Pool]
오브젝트 풀링 구현

네트워크 성능을 고려한 블루프린트 설계

  1. Replication 최소화
  • 필요한 변수와 함수만 Replicate 설정
  1. RPC (Remote Procedure Calls) 효율적 사용
  • 과도한 RPC 호출 지양, 데이터 배치 처리
  1. Network Relevancy 활용
  • 관련 없는 클라이언트에 불필요한 데이터 전송 방지
[Custom Event: UpdateState]
Replicates: Run on Server
    |
[Set Replicated Variable]
    |
[Multicast Event: BroadcastUpdate]
네트워크 최적화 블루프린트

C++로의 전환 고려

  1. 전환이 필요한 상황
  • 높은 성능이 요구되는 계산 집약적 기능
  • 매우 자주 호출되는 함수
  • 대규모 데이터 처리
  1. 블루프린트 함수 라이브러리 사용
  • C++ 함수를 블루프린트에서 호출 가능하게 만들기
UFUNCTION(BlueprintCallable, Category = "Optimization")
static float ComplexCalculation(float InputValue);
  1. 하이브리드 접근
  • 성능 중요 부분은 C++로, 빠른 반복이 필요한 부분은 블루프린트로 구현
C++ 및 블루프린트 하이브리드 구조

성능과 개발 용이성의 균형

  1. 프로파일링 기반 최적화
  • 실제 병목 지점 식별 후 최적화 진행
  1. 점진적 최적화
  • 기능 구현 후 단계적으로 최적화 진행
  1. 코드 리뷰 및 최적화 가이드라인 수립
  • 팀 내 최적화 기준 공유 및 정기적 리뷰
  1. 자동화된 성능 테스트 구축
  • CI / CD 파이프라인에 성능 테스트 통합
[Automated Test]
    |
[Run Performance Critical Scenarios]
    |
[Compare Results with Baseline]
    |
[Generate Performance Report]
자동화된 성능 테스트 흐름

 블루프린트 성능 최적화는 게임의 전반적인 품질과 사용자 경험에 직접적인 영향을 미치는 중요한 과정입니다. 단순히 성능만을 고려하는 것이 아니라, 개발 효율성과의 균형을 잘 맞추는 것이 중요합니다.

 최적화 과정에서 가장 중요한 것은 실제 데이터에 기반한 접근입니다. 프로파일링 도구를 적극 활용하여 실제 병목 지점을 정확히 파악하고, 그에 따른 최적화 전략을 수립해야 합니다. 또한, 최적화는 지속적이고 반복적인 과정이어야 합니다. 새로운 기능이 추가되거나 기존 시스템이 변경될 때마다 성능 영향을 평가하고 필요한 조치를 취해야 합니다.

 팀 전체가 성능 최적화의 중요성을 인식하고, 공통된 가이드라인을 따르는 것도 중요합니다. 정기적인 코드 리뷰와 성능 검토 세션을 통해 팀 전체의 최적화 역량을 높이고, 일관된 접근 방식을 유지할 수 있습니다.

 마지막으로, C++로의 전환은 신중하게 결정해야 합니다. 블루프린트의 빠른 반복 개발 이점과 C++의 성능 이점을 적절히 조화시키는 하이브리드 접근이 많은 경우에 효과적일 수 있습니다. 프로젝트의 규모, 팀의 기술 스택, 개발 일정 등을 종합적으로 고려하여 최적의 전략을 선택해야 합니다.