3 분 소요

프로파일링 - 최적화 하기 전에 프로파일링을 해야함 프로파일러는 누가 하는가 ? 프로그래머가 주 책임자이다. 프로그래머가 먼저 프로파일링을 하고 그 후에 TA나 그래픽팀에서 작업을 하는게 좋다.

프로파일할 때 출시 직전에 최적화를 진행하기 x

프로파일링은 분기에 1번 씩 주기적으로 진행 또 타겟 디바이스에서 진행을 해봐야한다. 에디터에서 돌리는 프로파일링은 부정확함 모바일 기기 성능이랑 pc성능이랑 다른 것 처럼 꼭 타겟 디바이스로 진행 (xCode로 진행하면 좋음)

fps로 판단하기에는 병목측정하기에는 힘들다. ms(밀리세컨드)로 병목 판단하기 (fps = 1000/ms, ms = 1000/fps)

병목이 cpu바운더리인지 gpu 인지 체크 꼭 하기

디바이스 온도 체크하기 모바일은 열이 오르면 성능을 떨구기(쓰로틀링) 때문에 두 상황 다 책정해야함

해상도에 따라서 병목 위치가 달라질 수 있음 따라서 주 타겟층을 생각해서 해야함

메모리 모바일에서는 메모리를 타이트하게 써야한다. 넘으면 터짐 C++에서는 Delete가 있지만 C#에서는 GC를 사용 GC가 호출하면서 메모리 재배치등 진행하면서 메모리 압축을 하는데 연산에 문제가 있다. 프레임이 살짝씩 튈 때는 GC가 문제일 경우가 많으니 new를 많이 하거나 메모리 할당을 많이 하면 안된다.

—— 코딩

애니메이션에서 m_Animator.SetBool(“Jump”, true); 이 코드에서 string을 직접 입력하는건 GC를 계속 사용하게 됨 따라서 파라미터에 ID를 입력하는게 효율적임 (한 두번은 당연히 상관없음)

코루틴 yield retrun new wati~~ 에서 new가 계속 발생하기에 GC가 생김 따라서 캐싱을 해야한다.

생명주기 다시 보기 실행 순서를 잘 알아야 성능을 관리하기 편하다 #if UNITY_EDITOR 함수(){} #endif 이렇게 에디터에서 사용하는 함수는 릴리즈에 사용이 안됨 Debug.Log는 빌드하면 사라지는게 아니니 꼭 삭제 하거나 System.Diagnostics.Conditional(“ENABLE_LOG”)를 사용해서 디버그를 막자

컴포넌트를 실시간으로 붙혔다 제거하는 행위는 성능을 많이 먹는다. ex) 몬스터별로 컴포넌트를 다르게 스크립트를 통해서 제어하는게 아니라 각각의 몬스터를 프리팹으로 만들어서 사용하자

Find, GetComponent, Camera.main은 update가 아닌 start에서 사용하는걸 권장한다.

오브젝트 풀은 꼭 사용하자

유니티 버전마다 부모를 재설정하는 비용이 다르긴 하지만 되도록 사용하지 말자 (하이어라키창에서 보기 안 좋더라도 그냥 마음을 비우고 하자)

스크랩터블 오브젝트는 유니티 튜토리얼에서 알려주니까 꼭 해보자


프로젝트 설정창

안 쓰거나 필요없는건 대부분 꺼라 Auto Graphics API(OpenGl 2나3를 사용하면 벌칸을 끄자 반대상황도)

물리연산은 FixedUpdate에서 다루자 (사용하지 않으면 설정에서 다 끄자 Auto Simulation, Auto Sync Transform)

FrameRate정책을 만들어 구현하는게 좋다.

하이어라키창에서 자식이 많으면 많을수록 부모를 움직일 때 자식 모두가 움직이게 되니까 연산이 많이 들어간다. 이것도 생각해서 구현하자

또 a,b,c오브젝트가 서로 종속관계가 아니라면 멀티 스레드를 활용해서 연산을 할 수 있다.

따라서 하이어라키는 간단하게 할수록 이득을 본다.

여러 스크립트에서 트랜스폼을 건들이면 안 좋기에 고려하자 ex) Player에 Move.cs, Jump.cs, Dash.cs, Dodge.cs 4스크립트 모두 트랜스폼을 사용)

핸드폰에서는 V Sync(수직동기화)를 자동으로 켜주니 그냥 킨다고 생각하는게 좋다.

Assets

JPG, PNG, PSD, PSB등 어떤 포멧을 가져와도 유니티에서 포멧을 재변환하기에 어떤 포멧을 가져와도 똑같으니 관리하기 편한(포토샵 작업 후 PNG로 변환하기 번거롭기 때문에) PSD, PSB(작업 pc는 성능이 좋기 때문에 에디터에서 사용은 문제 없음 최종 빌드에는 어차피 영향x)를 쓰자 (사운드도 마찬가지 mp3보단 wav가 좋음 mp3는 재압축하기 때문에)

텍스쳐는 플랫폼별로 오버라이딩이 가능함 디폴트는 설정이 없기에 설정을 해주는게 좋음 최신폰도 4096은 안됨 2048을 쓰자

2d 타일은 개별 파일로 만들어서 Textures Atlas로 묶자

Read/Write Enabled옵션은 웬만하면 끄는게 좋다. 저장소에서 CPU로 이동 후 GPU로 이동하기에 비효율적(중복)이다 따라서 동적으로 관리하는게 아니라면 끄자

Generate Mip Maps 512짜리 텍스쳐가 있다면 256,128….등 작은 사이즈의 텍스쳐를 생성한다. 따라서 메모리가 33%정도 뻥튀기됨 따라서 2D에서는 필요가 없지만 3D에서는 필요하다.

텍스쳐 압축은 무조건 사용해야한다. ASTC(포멧)를 사용하는게 좋음 - 최신폰 기준 (동남아는 x)

Compress the mesh는 눈으로 확인하면서 타협

Disable Read/Write는 동적으로 텍스쳐를 사용하는게 아니라면 끄자 (mmorpg종류는 끄는게 맞음)

Disable rigs and BlendShapes도 끄자 (단 캐릭터 표정같이 Blend를 사용하는 경우를 제외)

노말 맵을 사용하지 않은 오브젝트는 tangents를 끄자

위의 옵션들을 자동 체크를 하는 에셋 프로세서가 있다. 그래픽팀과 상의해서 조절할 것


Graphics

URP(Universal Render Pipeline)사용하면 절약(배칭부분)하는 부분이 많다.

Frame Debugger로 Draw Call을 확인 할 수 있다.

동적 라이팅을 사용할 수 있다.(그래도 정적을 사용하는게 좋음)

Disable shadows가능 그림자 정책을 세우는게 가장 베스트

라이트 맵 : 빛의 결과물을 텍스쳐로 만듦

Occlusion Culling(카메라가 앞에 있는 오브젝트로 인해 뒤에 보이지 않은 오브젝트를 드로우하지 않음) 건물같은 맵에서는 효율적이나 오픈월드처럼 아웃도어에서는 오히려 비효율적이다.


UI

Draw Call이 Canvas단위로 일어난다.

Canvas는 정적과 동적으로 나누면 성능면에서 좋다.

Graphic Raycast, Raycast target은 끄는게 좋다.(button처럼 상호작용이 필요한 케이스를 제외 canvas에는 컴포넌트를 제거하고 필요한 오브젝트에 컴포먼트를 따로 붙혀주면 효율적임) - 물론 버튼이 1~2개면 상관없음

Grid Layout Groups는 동적으로 작동하기 때문에 사용 지양하고 사용 다 하면 끄는걸 추천

UI도 풀링을 꼭 사용

디바이스 시뮬레이터는 적극적으로 사용하는걸 추천


Audio

웬만하면 mono로 하는걸 추천 (pc는 x)

원본파일은 WAV를 사용하는걸 추천 어차피 재압축함

Compression Format - Vorvis사용(유니티는 사운드를 F Mod엔진을 사용함 멀티 스레드를 사용하기에)권장

짧은 Sound는 ADPCM포멧을 사용

Load Type이 가장 중요! 사운드를 메모리에 어떻게 올릴지

  • Decompress on Load : 압축을 전부 풀어서 올림 (메모리 비효율 총알 발사 사운드나 발자국처럼 작은 사운드에 추천)
  • Compressed in Memory : 압축한 상태로 메모리에 올림(중간 크기 사운드)
  • Streaming : 필요한 부분만 꺼냈다 썼다 하기에 배경음은 해당 옵션을 사용

volume이 0이여도 연산은 처리가 됨 따라서 없애버리는게 좋음


Animation

Generic이냐 Humanoid냐 휴머노이드는 메모리를 30-50% 더 소모한다. 애니메이션 리타게팅 문제가 없다면 제네릭 사용 권장


Physics

Prebake Collision Meshes는 로딩 타임에 콜라이더를 미리 굽는다. 따라서 그냥 쓰는게 좋음

Collision Matrix는 잘 체크하자 (총알이 플레이어를 통과하거나 이런거)

콜라이더는 기본 도형을 사용하는게 가장 좋음 (기본 콜라이더는 최적화가 잘 됨)

Physics Debug를 비주얼적으로 체크가 가능하니 써보는걸 추천

태그:

카테고리:

업데이트: