이 글은 Unity 프로젝트를 위한 최적화 팁을 소개하는 시리즈 중 첫 번째 글입니다. 더 적은 리소스로 더 높은 프레임 속도로 실행하기 위한 가이드로 활용하세요. 이러한 모범 사례를 시도해 본 후에는 시리즈의 다른 페이지도 확인해 보세요:
기본 설정에 의존하지 마세요. 플랫폼별 재정의 탭을 사용하여 텍스처 및 메시 지오메트리와 같은 에셋을 최적화할 수 있습니다. 설정이 잘못되면 빌드 크기가 커지고 빌드 시간이 길어지며 GPU 성능과 메모리 사용량이 저하될 수 있습니다. 사전 설정 기능을 사용하여 프로젝트의 기준 설정을 추가로 사용자 지정 하는 것도 고려해 보세요.
아트 에셋 작업에 대한 모범 사례는 이 가이드를 참조하세요. 모바일 전용 가이드는 모바일 애플리케이션을 위한 3D 아트 최적화에 대한 Unity Learn 강좌를 확인하세요.
플레이어 설정에서 자동 그래픽 API를 비활성화하고 각 타겟 플랫폼에 대해 지원할 계획이 없는 추가 그래픽 API를 제거합니다. 이렇게 하면 과도한 셰이더 배리언트가 생성되는 것을 방지할 수 있습니다. 애플리케이션에서 구형 CPU를 지원하지 않는 경우 대상 아키텍처 설정을 비활성화합니다.
그래픽 API에 대해 자세히 알아보세요.
스크립팅 백엔드를 모노에서 IL2CPP (중간 언어에서 C++로)로 전환하면 전반적으로 런타임 성능이 향상될 수 있습니다. 하지만 빌드 시간이 늘어날 수도 있습니다. 일부 개발자는 더 빠른 반복을 위해 로컬에서 Mono를 사용한 다음 빌드 머신 및/또는 릴리스 후보를 위해 IL2CPP로 전환하는 것을 선호합니다. 빌드 시간 단축에 대한 자세한 내용은 IL2CPP 빌드 시간 최적화 문서를 참조하세요.
참고: 이 옵션을 사용하면 Unity는 타겟 플랫폼용 네이티브 바이너리 파일(.exe, .apk, .xap)을 생성하기 전에 스크립트 및 어셈블리에서 ILcode를 C++로 변환합니다.
다양한 컴파일러 옵션이 런타임 성능에 어떤 영향을 미치는지 알아보려면 IL2CPP 내부 소개를 참조하거나 컴파일러 옵션 매뉴얼 페이지를 참조하세요.
모바일 프로젝트는 프레임 속도와 배터리 수명 및 열 스로틀링의 균형을 맞춰야 합니다. 초당 프레임 수(fps)를 생각해보세요.
60fps로 디바이스의 한계를 뛰어넘는 대신 30fps로 실행하는 것을 타협점으로 고려해 보세요. 유니티는 이미 모바일용 기본값을 30fps로 설정하고 있습니다.
또한 런타임 중에 Application.targetFrameRate를 사용하여 프레임 속도를 동적으로 조정할 수도 있습니다. 예를 들어 느리거나 비교적 정적인 장면(메뉴 등)에서는 30fps 이하로 낮추고 게임 플레이를 위해 더 높은 fps 설정을 예약할 수 있습니다.
모바일 플랫폼에서는 하프프레임이 렌더링되지 않습니다. 에디터(프로젝트 설정 > 퀄리티)에서 Vsync를 비활성화하더라도 하드웨어 레벨에서는 여전히 활성화됩니다. GPU가 충분히 빠르게 새로고침할 수 없는 경우 현재 프레임이 유지되어 결과적으로 프레임이 감소합니다.
자세한 내용은 문서에서 확인할 수 있습니다.
유니티는 모바일의 가속도계를 초당 여러 번 폴링합니다. 애플리케이션에서 사용하지 않는 경우 비활성화하거나 더 나은 성능을 위해 사용 빈도를 줄이세요.
가속도계에 대해 자세히 알아보세요.
계층 구조를 분할하세요. 게임 오브젝트를 계층구조에 중첩할 필요가 없는 경우, 부모를 단순화하세요.
계층 구조가 작을수록 씬의 트랜스폼을 새로 고치는 데 멀티스레딩이 유용합니다. 계층 구조가 복잡하면 불필요한 트랜스폼 계산과 가비지 컬렉션 (GC) 비용이 발생합니다.
트랜스폼에 대한 팁은 계층 구조 최적화하기와 이 유나이트 강연을 참조하세요.
위의 두 예는 동일한 모델과 텍스처를 사용하지만, 상단의 설정은 하단의 설정에 비해 메모리를 5배 이상 더 많이 사용하면서도 시각적 품질은 크게 향상되지 않습니다.
텍스처 압축을 올바르게 적용하면 로드 시간 단축, 메모리 사용량 감소, 렌더링 성능의 획기적인 향상 등 상당한 성능 이점을 얻을 수 있습니다. 압축 텍스처는 비압축 32비트 RGBA 텍스처에 필요한 메모리 대역폭의 일부만 사용합니다.
대상 플랫폼용 텍스처 압축 포맷 권장 목록을 참조하세요.
텍스처는 잠재적으로 과도한 리소스를 사용할 수 있으므로 임포트 설정을 최적화하는 것이 중요합니다. 일반적으로 다음 가이드라인을 따르세요:
- 최대 크기 낮추기: 시각적으로 허용되는 결과를 생성하는 최소 설정을 사용합니다. 이 방법은 비파괴적이며 텍스처 메모리를 빠르게 줄일 수 있습니다.
- 2의 거듭제곱(POT) 사용: Unity는 텍스처 압축 포맷에 POT 텍스처 치수를 요구합니다.
- 읽기/쓰기 활성화 옵션 끄기: 이 옵션을 활성화하면 CPU와 GPU 주소 지정 가능 메모리 모두에 사본을 생성하여 텍스처의 메모리 사용 공간을 두 배로 늘립니다. 대부분의 경우 비활성화하고 런타임에 덮어써야 하는 텍스처를 생성하는 경우에만 활성화합니다. Texture2D.Apply를 통해 이 옵션을 적용하고 makeNoLongerReadable을 True로 설정할 수도 있습니다.
- 불필요한 밉 맵 비활성화: 2D 스프라이트 및 UI 그래픽과 같이 화면에서 일정한 크기로 유지되는 텍스처에는 밉 맵이 필요하지 않습니다. 그러나 카메라와의 거리가 다른 3D 모델에 대해서는 맵 맵을 활성화한 상태로 둡니다.
텍스처 임포트 설정에 대해 자세히 알아보세요.
아틀라싱은 여러 개의 작은 텍스처를 하나의 큰 텍스처로 그룹화하는 프로세스입니다. 텍스처 아틀라스는 메모리 사용량을 줄이고 드로우 콜을 적게 요구하므로 GPU에 필요한 노력이 줄어듭니다.
- 2D 프로젝트의 경우: 사용 스프라이트 아틀라스(에셋 > 생성 > 2D > 스프라이트 아틀라스)를 사용하여 개별 스프라이트나 텍스처를 렌더링하는 대신 스프라이트 아틀라스를 사용합니다.
- 3D 프로젝트의 경우: 원하는 디지털 콘텐츠 제작 (DCC) 패키지를 사용할 수 있습니다. 다음과 같은 여러 서드파티 툴 MA_TextureAtlasser 나 TexturePacker 와 같은 여러 타사 툴을 사용하여 텍스처 아틀라스를 빌드할 수도 있습니다.
고해상도 맵이 필요하지 않은 3D 지오메트리에 텍스처를 결합하고 UV를 리매핑할 수 있습니다. 시각적 편집기를 사용하면 텍스처 아틀라스 또는 스프라이트 시트에서 크기와 위치를 설정하고 우선 순위를 지정할 수 있습니다.
텍스처 패커는 개별 맵을 하나의 큰 텍스처로 통합합니다. 그러면 Unity는 단일 드로우 호출을 실행하여 성능 오버헤드를 줄이면서 패킹된 텍스처에 액세스할 수 있습니다.
여기에서 스프라이트 아틀라스에 대해 자세히 알아보세요.
고해상도 모델에는 더 많은 메모리 사용량과 잠재적으로 더 많은 GPU 작업이 필요합니다. 따라서 씬에서 게임 오브젝트의 기하학적 복잡성을 최소화하는 것을 목표로 하세요. 그렇지 않으면 Unity가 중요한 버텍스 데이터를 그래픽 카드에 푸시해야 합니다.
가장 좋은 방법은 DCC 소프트웨어에서 모델을 축소하고 카메라의 관점에서 보이지 않는 폴리곤을 삭제하는 것입니다. 예를 들어, 벽에 기대어 있는 찬장 뒷면이 보이지 않는다면 모델에 얼굴이 없어야 합니다.
최신 GPU에서 병목 현상은 일반적으로 폴리곤 수가 아닌 폴리곤 밀도와 관련이 있다는 점에 유의하세요. 모든 에셋에 아트 패스를 수행하여 원거리 오브젝트의 폴리곤 수를 줄이세요. 마이크로트라이앵글은 GPU 성능 저하의 중요한 원인이 될 수 있습니다.
대상 플랫폼에 따라 고해상도 텍스처를 통해 디테일을 추가하여 로우 폴리 지오메트리를 보완하는 것도 고려해 보세요. 메시의 밀도를 높이는 대신 텍스처와 노멀 맵을 사용합니다. 텍스처에 최대한 많은 디테일을 구워 픽셀 복잡도를 줄이세요. 예를 들어, 텍스처 자체에서 스페큘러 하이라이트를 캡처하여 조각 셰이더에서 하이라이트를 계산하지 않도록 할 수 있습니다.
정기적으로 프로필을 작성하는 것을 잊지 마세요. 결국 이러한 기술은 성능에 영향을 미치며 대상 플랫폼에 적합하지 않을 수 있습니다.
텍스처와 마찬가지로 메시도 신중하게 임포트하지 않으면 과도한 메모리를 소모할 수 있습니다. 메시의 메모리 소비를 최소화하려면 다음 팁을 참고하세요:
- 메시 압축: 메시 압축은 디스크 공간을 줄일 수 있습니다(런타임 시 메모리에는 영향을 미치지 않음). 동시에 메시 양자화는 부정확성을 초래할 수 있으므로 압축 수준을 실험하여 모델에 적합한 것이 무엇인지 확인합니다.
- 읽기/쓰기 비활성화: 이 옵션을 활성화하면 메시가 메모리에 복제되어 메시 사본 하나는 시스템 메모리에, 다른 하나는 GPU 메모리에 유지됩니다. 대부분의 경우 비활성화해야 합니다. Unity 2019.2 이하 버전에서는 이 옵션이 기본적으로 선택되어 있습니다.
- 릭 및 블렌드 셰이프를 비활성화합니다: 메시에서 스켈레탈 또는 블렌드 셰이프 애니메이션이 필요하지 않은 경우, 이 옵션을 비활성화합니다.
- 노멀과 탄젠트를 비활성화합니다: 메시의 머티리얼에 노멀이나 탄젠트가 필요하지 않다고 확신하는 경우, 이 옵션을 선택 해제하면 비용을 추가로 절약할 수 있습니다.
추가 메시 최적화 옵션은 플레이어 설정에서 사용할 수 있습니다:
- 버텍스 압축은 각 채널의 버텍스 압축을 설정합니다. 예를 들어 포지션과 라이트맵 UV를 제외한 모든 항목에 압축을 활성화할 수 있습니다. 이렇게 하면 메시의 런타임 메모리 사용량을 줄일 수 있습니다.
- 참고: 각 메시의 임포트 세팅에 있는 메시 압축 세팅은 버텍스 압축 세팅을 덮어씁니다. 이 경우 메시의 런타임 사본은 압축되지 않으며 더 많은 메모리를 사용할 수 있습니다.
- 메시 데이터 최적화는 메시에서 적용된 머티리얼에 필요하지 않은 데이터(예: 탄젠트, 노멀, 색상 및 UV)를 제거합니다.
감사 프로세스를 자동화하면 실수로 자산 설정을 변경하는 것을 방지할 수 있습니다. 에셋 포스트 프로세서 에셋포스트프로세서 는 임포트 설정을 표준화하거나 기존 에셋을 분석하는 데 도움이 될 수 있습니다. 에셋을 임포트할 때 스크립트를 실행할 수 있으며, 기본적으로 모델, 텍스처, 오디오 등을 임포트하기 전 및/또는 후에 설정을 사용자 지정하라는 메시지를 표시합니다.
최적화 이해 가이드에서 자산 감사에 대해 자세히 알아보세요.
Unity는 링 버퍼를 사용하여 텍스처를 GPU로 푸시합니다. 이 비동기 텍스처 버퍼는 QualitySettings.asyncUploadBufferSize를 통해 수동으로 조정할 수 있습니다.
업로드 속도가 너무 느리거나 여러 텍스처를 한 번에 로드하는 동안 메인 스레드가 멈추는 경우 텍스처 버퍼를 조정하세요. 일반적으로 씬에서 로드해야 하는 가장 큰 텍스처의 크기(MB)로 값을 설정할 수 있습니다.
기본값을 변경하면 메모리 부담이 커질 수 있다는 점에 유의하세요. 또한 Unity가 링 버퍼 메모리를 할당하고 나면 시스템에 반환할 수 없습니다. GPU 메모리가 과부하되면 GPU는 가장 최근에 가장 적게 사용된 텍스처를 언로드하고 다음에 카메라 프러스텀에 들어갈 때 CPU가 이를 강제로 다시 업로드합니다.
메모리 관리 튜토리얼에서 텍스처 버퍼에 대한 모든 메모리 제한 사항을 살펴보고 로딩 성능 최적화를 참조하여 로딩 시간을 개선할 수 있는 방법을 알아보세요.
그리고 밉 맵 스트리밍 시스템을 사용하면 메모리에 로드할 밉 맵 레벨을 제어할 수 있습니다. Unity의 퀄리티 설정(편집 > 프로젝트 설정 > 퀄리티)으로 이동하여 텍스처 스트리밍 옵션을 체크하여 활성화합니다. 고급의 텍스처 임포트 세팅에서 밉 맵 스트리밍을 활성화할 수 있습니다.
이 시스템은 현재 카메라 위치를 렌더링하는 데 필요한 밉 맵만 로드하므로 텍스처에 필요한 총 메모리 양을 줄입니다. 그렇지 않으면 Unity가 기본적으로 모든 텍스처를 로드합니다.
텍스처 스트리밍은 소량의 CPU 리소스를 교환하여 잠재적으로 많은 양의 GPU 메모리를 절약할 수 있습니다. 또한 밉 맵 레벨을 자동으로 줄여 사용자가 정의한 메모리 예산 내에서 유지합니다.
밉 맵 스트리밍 API를 사용하여 추가 제어를 할 수 있습니다.
주소 지정 가능 자산 시스템 어드레서블 에셋 시스템 은 게임을 구성하는 에셋 관리를 간소화합니다. 씬, 프리팹, 텍스트 에셋 등 모든 에셋을 주소 지정 가능으로 표시하고 고유한 이름을 지정할 수 있습니다. 그런 다음 어디서나 이 별칭을 호출할 수 있습니다.
게임과 에셋 사이에 이러한 추상화 수준을 추가하면 별도의 다운로드 가능한 콘텐츠 팩을 만드는 것과 같은 특정 작업을 간소화할 수 있습니다. 어드레서블을 사용하면 로컬이든 원격이든 상관없이 에셋 팩을 쉽게 참조할 수 있습니다.
패키지 관리자에서 어드레서블 패키지를 설치합니다. 프로젝트의 각 에셋 또는 프리팹은 결과적으로 '어드레서블'이 될 수 있습니다.
인스펙터에서 에셋의 이름 아래 옵션을 선택하면 기본 고유 주소가 할당됩니다. 표시가 완료되면 해당 자산이 창 > 자산 관리 > 주소 지정 가능 항목 > 그룹 창에 나타납니다.
자산이 다른 곳에서 호스팅되든 로컬에 저장되든, 시스템은 주소 지정 가능 이름 문자열을 사용하여 자산의 위치를 찾습니다. 어드레서블 프리팹은 필요할 때까지 메모리에 로드되지 않으며, 더 이상 사용하지 않을 때는 관련 에셋을 자동으로 언로드합니다. 어드레서블로 메모리 절약하기 블로그 게시물에서는 어드레서블 그룹을 구성하여 메모리를 보다 효율적으로 사용할 수 있는 방법을 설명합니다.
주소 지정 가능 항목을 참조하세요: 프로젝트에서 어드레서블 에셋 시스템을 사용하는 방법에 대한 간략한 개요는 개념 소개 를 참조하세요.
가장 포괄적인 가이드 중 하나로, PC 및 콘솔용 게임을 최적화하는 방법에 대한 80개 이상의 실행 가능한 팁을 모았습니다. 유니티의 성공 및 가속화 솔루션 전문 엔지니어가 작성한 이 심층적인 팁은 Unity를 최대한 활용하고 게임 성능을 향상하는 데 도움이 될 것입니다.