메모리 및 CPU 사용량 최적화
이전 절에서 렌더링 및 광원 설정을 조정하여 주로 GPU 성능을 최적화하는 방법을 배웠습니다. 이제 게임의 또 다른 핵심 자원인 메모리(Memory) 사용량과 CPU(Central Processing Unit) 사용량을 효율적으로 관리하고 최적화하는 방법에 대해 알아볼 차례입니다. 메모리 부족은 게임 충돌로 이어질 수 있으며, 과도한 CPU 사용량은 프레임 드랍을 유발합니다. 특히 복잡한 게임 로직, AI, 물리 시뮬레이션 등은 CPU에 직접적인 부담을 주며, 자산 로딩 및 스트리밍은 메모리 관리에 중요합니다. '나 혼자 언리얼 기본' 교재를 통해 여러분이 언리얼 엔진에서 메모리 및 CPU 사용량을 분석하고 최적화하여, 게임이 더욱 안정적이고 부드럽게 실행되도록 안내해 드리겠습니다. 마치 복잡한 컴퓨터 시스템의 각 구성 요소가 효율적으로 작동하도록 조율하듯, 여러분의 게임도 메모리와 CPU 자원을 최적으로 활용해 봅시다.
메모리 및 CPU 사용량 최적화의 중요성
메모리 및 CPU 최적화는 GPU 최적화만큼이나 게임의 안정성과 성능에 결정적인 영향을 미칩니다.
- 게임 안정성: 메모리 부족(OOM: Out Of Memory)은 게임 충돌의 가장 흔한 원인 중 하나입니다. 효율적인 메모리 관리는 게임의 안정성을 보장합니다.
- 프레임 속도 (FPS) 유지: CPU는 게임 로직, 물리, AI, 애니메이션 등 다양한 계산을 담당하므로, CPU 사용량이 높으면 프레임 드랍이 발생합니다.
- 로딩 시간 단축: 불필요한 메모리 사용량을 줄이면 게임 로딩 시간을 단축할 수 있습니다.
- 빌드 크기 감소: 사용하지 않거나 중복된 자산을 제거하여 최종 게임 빌드 크기를 줄일 수 있습니다.
- 멀티태스킹 환경 고려: 게임이 백그라운드에서 실행되거나 다른 앱과 동시에 실행될 때, 메모리 사용량이 적을수록 시스템 전반의 안정성이 높아집니다. (특히 모바일)
메모리 사용량 최적화
메모리(RAM 및 VRAM)는 게임이 실행되는 동안 모든 자산과 데이터가 로드되는 공간입니다. 효율적인 관리가 필수적입니다.
자산(Asset) 메모리 최적화
- 텍스처 해상도 및 압축
- 재강조: 9장 2절에서 다룬 텍스처 해상도(Max Texture Size)와 압축 설정(
Compression Settings
)은 VRAM 사용량에 가장 큰 영향을 미칩니다. 불필요하게 고해상도 텍스처를 사용하지 않고, 적절한 압축 설정을 적용합니다. (예: 노멀맵은Normalmap
압축, 알파 없는 컬러는Default (DXT1)
)
- 재강조: 9장 2절에서 다룬 텍스처 해상도(Max Texture Size)와 압축 설정(
- 메시 LOD 및 디시메이션
- 재강조: 메시의 폴리곤 수가 많을수록 메모리에 더 많은 버텍스 데이터가 저장됩니다. LOD를 사용하여 멀리 있는 오브젝트의 메모리 사용량을 줄입니다.
- 오디오 압축
- 설정: 오디오 에셋(
Sound Wave
) 더블클릭 후Details
패널의Compression Settings
를 조정합니다. - 활용: 배경 음악이나 긴 사운드는
ADPCM
또는OGG
압축을 사용하고, 짧은 효과음은PCM
또는ADPCM
을 사용하되 비트레이트를 조절합니다.
- 설정: 오디오 에셋(
- 애니메이션 압축
- 설정: 스켈레탈 메시의 애니메이션 시퀀스(
Animation Sequence
) 에셋에서Compression
섹션을 조정합니다. - 활용:
Animation Compression
알고리즘(예:Remove Linear Keys
,Compress None
)을 변경하여 파일 크기와 런타임 메모리를 최적화합니다.
- 설정: 스켈레탈 메시의 애니메이션 시퀀스(
자산 로딩 및 언로딩
- 스트리밍 (Streaming) 레벨
- 역할: 레벨 전체를 한 번에 로드하는 대신, 플레이어가 특정 영역에 진입했을 때 해당 레벨 섹션만 로드하고, 벗어나면 언로드하여 메모리 사용량을 관리합니다.
- 활용: 광활한 오픈 월드나 매우 큰 레벨에서 필수적입니다.
- 설정:
월드 아웃라이너(World Outliner)
패널에서창(Window) > 레벨(Levels)
패널을 열어 서브 레벨(Sub-levels)을 추가하고 관리합니다. 각 서브 레벨의스트리밍 방식(Streaming Method)
을Blueprint
또는Always Loaded
등으로 설정합니다.
- 비동기 자산 로딩 (Asynchronous Asset Loading)
- 역할: 게임이 실행되는 동안 필요한 자산(메시, 텍스처 등)을 백그라운드에서 로드하여 메인 스레드(Main Thread)의 멈춤 현상(Stuttering)을 방지합니다.
- 활용: 로딩 화면 없이 끊김 없는 게임 플레이를 구현할 때 중요합니다.
- 구현:
Load Asset
또는Load Class
노드를 사용하여 블루프린트에서 비동기 로딩을 시작할 수 있습니다.
- 가비지 컬렉션 (Garbage Collection)
- 역할: 더 이상 사용되지 않는 오브젝트의 메모리를 회수합니다.
- 설정:
Project Settings > Engine > Garbage Collection
에서Time Between Purging
(GC 주기),Min Object Count
등을 조정할 수 있습니다. - 강제 GC: 특정 시점(예: 레벨 전환)에
Collect Garbage
노드를 호출하여 명시적으로 가비지 컬렉션을 실행할 수 있습니다. (CPU 스파이크 유발 가능성 있음)
인스턴싱 (Instancing)
- 역할: 동일한 메시를 여러 번 반복해서 배치할 때, 각각의 액터를 개별적으로 렌더링하지 않고 하나의 드로우 콜로 렌더링하는 기법입니다.
- 활용: 나무, 풀, 돌멩이, 동일한 건물 부품 등 반복적으로 사용되는 스태틱 메시에 사용합니다.
- 컴포넌트:
Hierarchical Instanced Static Mesh Component (HISM)
또는Instanced Static Mesh Component (ISM)
컴포넌트를 사용하여 구현합니다. 이들은 배치된 인스턴스들의 트랜스폼 데이터만 저장하므로 메모리와 CPU 부하를 크게 줄입니다. (LOD와 컬링도 지원)
CPU 사용량 최적화
CPU는 게임의 모든 로직과 계산을 담당하므로, 비효율적인 로직은 프레임 드랍의 주요 원인이 됩니다.
블루프린트 및 C++ 로직 최적화
Event Tick
활용 최소화- 핵심:
Event Tick
은 매 프레임마다 호출되므로, 여기에 복잡한 로직을 넣는 것은 CPU 부하를 크게 증가시킵니다. - 대안:
Set Timer by Event
를 사용하여 주기적인 업데이트 로직을 0.1~0.5초 간격으로 실행하거나, 특정 이벤트(예: 플레이어 입력, 충돌)가 발생할 때만 로직을 실행합니다. - 활용: 오브젝트 상태 확인, UI 업데이트, AI 행동 업데이트 등.
- 핵심:
- 루프(Loop) 최적화
For Loop
,For Each Loop
등 반복문 내부에 너무 많은 연산이나 복잡한 함수 호출을 피합니다.- 대규모 배열을 순회하는 경우, 필요한 경우에만 루프를 실행하도록 조건을 추가합니다.
IsValid
및Branch
노드 활용IsValid
노드를 사용하여 유효하지 않은 오브젝트에 접근하는 것을 방지하고,Branch
노드를 사용하여 불필요한 로직이 실행되지 않도록 합니다.
- 캐싱(Caching) 참조
Get Actor Of Class
,Get All Actors Of Class
와 같이 레벨에서 특정 액터를 검색하는 노드는 비용이 높습니다.Event BeginPlay
에서 검색하여 변수에 저장(캐싱)한 후 재사용합니다.
- 불필요한 디버그 출력 제거
Print String
,Draw Debug
등의 디버그 노드는 개발 중에는 유용하지만, 최종 빌드에서는 제거하거나 비활성화해야 합니다. (개발 중에는Development Build
에서만 활성화되도록 할 수 있음)
물리 시뮬레이션 최적화
- 재강조: 7장 5절 "물리 시뮬레이션 성능 조정"에서 다룬 내용입니다. 물리 시뮬레이션은 CPU에 큰 부담을 줍니다.
Simulate Physics
활성화 오브젝트 수 제한.Simple Collision
적극 활용.- 물리 오브젝트 자동
Sleep
기능 활용. Max Physics Delta Time
,Max Substeps
등의 프로젝트 설정 조정.
AI (인공지능) 최적화
- 재강조: 9장 5절에서 더 자세히 다루겠지만, AI는 CPU 사용량의 주요 원인입니다.
- 거리 기반 AI 비활성화: 플레이어로부터 멀리 떨어진 AI는 행동 로직을 비활성화하거나, 매우 단순한 로직만 실행하도록 합니다.
- 행동 트리/블랙보드 최적화: 복잡한 행동 트리(Behavior Tree) 노드의 실행 빈도를 줄이고, 블랙보드(Blackboard) 쿼리 빈도를 최적화합니다.
- 내비게이션 메쉬 (Nav Mesh) 최적화: 필요한 영역에만
Nav Mesh
를 생성하고, 복잡도를 단순화합니다.
드로우 콜 (Draw Call) 최적화
- 재강조: 9장 2절에서 다룬
Merge Actors
및Instancing
은 CPU의 드로우 콜 준비 작업 부담을 줄입니다.- 배칭 (Batching): 언리얼 엔진은 동일한 재질과 메시를 사용하는 인접한 오브젝트들을 자동으로 배치하여 드로우 콜을 줄이려고 시도합니다.
- 어트라스 (Atlases): 여러 작은 텍스처를 하나의 큰 텍스처(텍스처 아틀라스)에 묶어 사용하여 머티리얼 수를 줄이고 드로우 콜을 절약할 수 있습니다.
메모리 및 CPU 사용량 분석 도구
Stat Unit
:Game
(CPU 로직) 및Draw
(CPU 드로우 콜) 시간을 통해 CPU 병목을 1차적으로 확인합니다.Stat Engine
: 엔진의 다양한 서브시스템(물리, 애니메이션, AI, 블루프린트 등)의 CPU 시간을 상세하게 보여주어 어느 부분이 가장 많은 시간을 소모하는지 파악합니다.Stat Memory
: 시스템 메모리 및 VRAM 사용량을 전반적으로 보여줍니다.Stat Raw
: 좀 더 상세한 메모리 통계를 보여줍니다.
Memreport
(콘솔 명령어):memreport -full
을 콘솔에 입력하면 현재 메모리 사용량에 대한 상세한 보고서가 출력 로그 또는 파일로 생성됩니다. 어떤 자산이 가장 많은 메모리를 차지하는지 확인할 수 있습니다.Unreal Insights
(언리얼 인사이트)- 역할: 언리얼 엔진 4.23 버전부터 제공되는 강력한 프로파일링 도구입니다. CPU, GPU, 메모리, 네트워킹 등 엔진의 거의 모든 활동을 시각적으로 상세하게 분석할 수 있습니다.
- 사용법:
UnrealEditor.exe -trace=cpu,gpu,memory,frame,log
등으로 엔진을 실행하고, 생성된.utrace
파일을UnrealInsights.exe
로 엽니다. - 활용: 특정 프레임에서 발생하는 CPU 스파이크의 원인(어떤 블루프린트 함수가 가장 오래 걸렸는지), 메모리 할당 패턴 등을 매우 상세하게 시각적으로 분석할 수 있습니다. (고급 기능)
Session Frontend
: 원격 장치에서 CPU/GPU 통계를 실시간으로 모니터링할 수 있는 도구입니다.
메모리 및 CPU 사용량 최적화는 게임의 안정성과 전반적인 성능에 깊이 관여합니다. 이 절에서 배운 자산 메모리 최적화, 로딩/언로딩 관리, 인스턴싱 활용, 그리고 블루프린트/AI/물리 로직 최적화 전략들을 바탕으로, 언리얼 엔진의 다양한 분석 도구를 활용하여 여러분의 게임을 더욱 효율적으로 만들어 나가세요. 지속적인 모니터링과 개선만이 모든 플레이어에게 끊김 없고 쾌적한 경험을 제공할 수 있습니다.