블루프린트 성능 최적화 기법
지금까지 우리는 언리얼 엔진에서 물리 시뮬레이션, 콜리전, 트레이싱, 날씨/시간 시스템, 동적 환경 상호작용 등 다양한 게임플레이 및 환경 요소를 구현하는 방법을 배웠습니다. 이러한 요소들은 게임의 몰입감과 재미를 크게 높여주지만, 동시에 성능(Performance) 에 상당한 영향을 미칠 수 있습니다. 특히 블루프린트만으로 복잡한 로직을 구현할 경우, 최적화를 고려하지 않으면 프레임 드롭이나 게임 멈춤 현상(Stutter)으로 이어질 수 있습니다.
이번 절에서는 언리얼 엔진의 블루프린트 성능을 최적화하기 위한 기본적인 기법들을 알아보겠습니다. C++ 개발과 달리 블루프린트만으로도 상당한 최적화를 이룰 수 있으며, 이는 특히 물리 및 환경 상호작용과 같은 동적인 요소들을 다룰 때 더욱 중요합니다.
왜 블루프린트 최적화가 필요한가?
블루프린트는 빠르고 직관적인 개발이 가능하지만, C++에 비해 상대적으로 낮은 성능을 가집니다. 이는 블루프린트가 가상 머신 위에서 해석되어 실행되기 때문입니다. 따라서 복잡하거나 반복적인 로직을 블루프린트로 작성할 때는 성능을 염두에 두어야 합니다.
최적화의 목표
- 프레임 레이트 안정화: 게임이 부드럽게 실행되도록 일관된 프레임 레이트를 유지합니다.
- 리소스 사용량 감소: CPU, GPU, 메모리 등의 리소스 사용량을 줄여 다양한 하드웨어에서 게임이 잘 작동하도록 합니다.
- 게임 반응성 향상: 입력 지연을 줄이고, 게임 내 상호작용이 즉각적으로 반응하도록 합니다.
블루프린트 성능 최적화 기본 기법
Event Tick
의 신중한 사용 및 비활성화
Event Tick
은 매 프레임마다 호출되는 이벤트이므로, 이곳에 너무 많은 또는 불필요한 로직이 포함되면 성능에 가장 큰 영향을 미칩니다.
- 불필요한 틱 비활성화: 액터가 항상 움직이거나 업데이트될 필요가 없다면
클래스 디폴트(Class Defaults)
에서Can Ever Tick
을 체크 해제합니다. - 필요할 때만 틱 활성화/비활성화: 캐릭터가 정지 상태일 때는 틱을 비활성화하고, 움직이기 시작할 때 다시 활성화하는 등, 필요한 순간에만
Set Actor Tick Enabled
노드를 사용하여 틱을 켜고 끄는 로직을 구현합니다. - 느린 틱(
Set Tick Interval
): 매 프레임 업데이트가 필요하지 않은 로직(예: 먼 거리의 AI 시야 체크, 특정 환경 효과 업데이트)은Set Tick Interval
노드를 사용하여 틱 주기를 늦춥니다. (예: 0.1초마다 틱)
캐싱(Caching) 및 변수 재사용
반복적으로 참조하는 액터, 컴포넌트, 또는 복잡한 계산 결과는 변수에 저장하여 반복적인 Get
노드 호출이나 재계산을 피합니다.
Cast
결과 캐싱:Cast To
노드는 상대적으로 비용이 큰 연산입니다. 한 번 캐스팅한 결과는 변수에 저장하여 나중에 재사용합니다.(Event BeginPlay 또는 On Component Begin Overlap) -> Cast To BP_PlayerCharacter -> Set PlayerCharacterRef (변수)
- 반복되는 계산 결과 저장: 루프 안에서 동일한 값을 반복적으로 계산하지 않도록, 루프 외부에서 한 번 계산하여 변수에 저장하고 루프 내에서는 이 변수를 사용합니다.
루프(Loop)와 배열/맵 처리 최적화
For Each Loop
나 While Loop
는 많은 요소를 처리할 때 성능 저하의 주범이 될 수 있습니다.
- 불필요한 루프 최소화: 루프를 돌기 전에 처리할 필요가 없는 데이터를 필터링합니다.
Break
노드 활용: 원하는 결과를 찾으면 즉시 루프를 중단합니다.Map
대신Array
고려: 단순히 순회하며 모든 요소를 처리하는 경우Array
가Map
보다 빠를 수 있습니다. 특정 키로 빠르게 조회해야 할 때만Map
을 사용합니다.- Large Array의 부분 처리: 매우 큰 배열을 매 프레임 순회하는 것을 피하고,
Set Timer by Event
등을 사용하여 여러 프레임에 걸쳐 나누어 처리합니다.
콜리전 및 트레이싱 최적화
물리 및 환경 상호작용의 핵심인 콜리전과 트레이싱은 올바르게 설정하지 않으면 성능 문제를 일으킵니다.
- 정확한 콜리전 프리셋 및 채널 사용:
BlockAll
대신Custom
설정을 사용하여 필요한 오브젝트 타입에만 응답하도록 합니다.Ignore
할 것은 확실히Ignore
합니다. - 단순한 콜리전 메시 사용: 스태틱 메시에
Complex Collision as Simple
을 사용하는 것을 피하고,Box
,Sphere
,Capsule
등 단순한 형태로 최적화된 콜리전 메시를 사용합니다. - 트레이스 거리 제한:
Line Trace
나Shape Trace
를 사용할 때End
지점을 실제 필요한 최소한의 거리로 제한합니다. - 필요할 때만 트레이스: 매 프레임마다 트레이스를 실행하는 대신, 특정 이벤트 발생 시에만 (예: 공격 버튼 누를 때, AI가 플레이어를 인지할 때) 트레이스를 실행합니다.
Multi Trace
대신Single Trace
고려:Multi Line Trace
는 모든 히트 결과를 반환하므로 비용이 더 큽니다. 가장 가까운 하나만 필요하다면Single Line Trace
를 사용합니다.
타이머(Timer) 및 딜레이(Delay) 활용
Event Tick
을 대체하여 주기적인 또는 지연된 실행이 필요한 로직에 활용합니다.
Set Timer by Event
/Set Timer by Function Name
: 일정 시간 간격으로 반복 실행되는 로직이나, 한 번만 지연 실행되는 로직에 사용합니다.Event Tick
보다 효율적입니다.Delay
: 특정 노드를 일정 시간 지연시킨 후 실행해야 할 때 사용합니다. 간단한 일회성 지연에 편리합니다.
컴포넌트 활성화/비활성화
불필요하게 리소스를 소모하는 컴포넌트(예: 파티클 시스템, 오디오 컴포넌트, 물리 컴포넌트)는 필요할 때만 활성화하고 사용 후에는 비활성화합니다.
Set Active
(파티클 시스템, 오디오 등)Set Simulate Physics
Set Component Tick Enabled
오브젝트 풀링(Object Pooling)
총알, 파티클 이펙트, 파편 등 게임 플레이 중 빈번하게 생성/파괴되는 액터의 경우, Spawn Actor
와 Destroy Actor
를 반복하는 대신 오브젝트 풀링을 사용하면 성능 오버헤드를 크게 줄일 수 있습니다.
- 미리 액터들을 생성해두고(Pool), 필요할 때 풀에서 가져와 사용하고, 사용이 끝나면 파괴하는 대신 풀로 반환하여 재활용합니다.
디버그 기능 비활성화
개발 단계에서 유용한 디버그 드로잉(예: Draw Debug Type
for traces)이나 Print String
노드는 게임 출시 전에 반드시 비활성화하거나 제거해야 합니다. 이들은 런타임 성능에 영향을 미칩니다.
적절한 클래스 선택
Pawn
vsCharacter
: 사람 형태의 움직임이 아니라면Character
대신Pawn
을 사용하고,CharacterMovementComponent
대신FloatingPawnMovement
나ProjectileMovementComponent
등 더 가벼운 이동 컴포넌트를 사용합니다.Actor
vsStatic Mesh Actor
: 단순히 메시와 콜리전을 가진 정적인 오브젝트라면Static Mesh Actor
를 사용하는 것이 더 최적화되어 있습니다. 커스텀 로직이 필요할 때만Actor
블루프린트를 사용합니다.
프로파일링 툴 활용
최적화는 '어디가 문제인지'를 아는 것에서 시작합니다. 언리얼 엔진은 강력한 프로파일링 툴을 제공합니다.
Stat Unit
/Stat FPS
: 기본적인 프레임 레이트 및 CPU/GPU 시간을 보여줍니다.Stat Game
/Stat Blueprint
: 게임 스레드와 블루프린트 실행에 대한 상세 통계를 보여줍니다.Stat Dump
: 현재 모든 통계를 파일로 저장합니다.Unreal Insights
: 더 정밀한 CPU 및 메모리 프로파일링 툴입니다.
이러한 툴을 사용하여 성능 병목 현상이 발생하는 부분을 정확히 파악하고, 해당 부분의 블루프린트 로직을 위에서 언급된 최적화 기법들을 사용하여 개선해야 합니다.
블루프린트 최적화는 지속적인 과정입니다. 게임을 개발하면서 주기적으로 성능을 측정하고, 잠재적인 병목 현상을 미리 예측하여 최적화된 로직을 설계하는 습관을 들이는 것이 중요합니다.
이번 절에서는 언리얼 엔진 블루프린트의 성능을 최적화하기 위한 다양한 기법들을 알아보았습니다. Event Tick
의 신중한 사용, 캐싱, 루프 최적화, 콜리전 설정, 타이머 활용, 오브젝트 풀링 등은 블루프린트 기반 게임의 안정적인 프레임 레이트와 부드러운 플레이 경험을 보장하는 데 필수적입니다.