참고 자료
[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리
http://www.slideshare.net/agebreak/unite2015-47100325?related=1
유니티 그래픽 최적화, 어디까지 해봤니
http://www.slideshare.net/ozlael/graphics-opt-ndc?related=2
최적화 내용 간단 정리
** 가장 중요한 것은 병목 지점 파악~(메모리인지, 콜인지, CPU인지, 버텍스연산인지.. 아니면 다함께..)
** 리소스 아껴 쓰기
** 드로우콜 관리하기
** 모바일 사운드는 모노로 사용하기~
** 가비지 컬렉터 관리~~
** 스크립트 함수에 무거운 함수 쓰지 않기~
** 셰이더에 무거운 함수 사용 줄이기~
** 물리 사용은 최소로~
1. 프로그램 최적화
* 스크립트 최적화
--- 유니티 객체들을 변수에 저장하고, 캐싱해서 사용하는 것이 좋다.
--- FindObject 계열 함수들은 매우 느리다. (미리 찾아서 캐싱)
--- Update 함수 보다는 Coroutine을 활용한다.
--- 박싱과 언박싱은 부하가 큰 작업이다.
--- 나눗셈보다 곱셈이 몇십배 빠르다.
--- 삼각함수의 값은 상수로 저장하고, 사용하는 것이 좋다.
--- 문자열은 readonly 혹은 const 키워드를 사용하여, 가비지 컬렉션으로부터 벗어나도록 한다.
* 문제의 원인 : 가비지 컬렉터
--- Mono의 동적 메모리 관리 때문에, 메모리 해제를 위해 GC가 자동 호출 된다.
--- GC는 언제 일어날지 모른다.
--- 오브젝트(or 프리팹)의 동적생성과 해제는 부하가 크다.
--- 오브젝트 풀링 사용은 선택이 아닌 필수!
--- 문자열 병합은 StringBuilder
--- foreach 대신에 for문 사용 (foreach는 한번 돌때마다 24Byte의 쓰레기 메모리를 생성)
--- 태그 비교에는 compareTag() 사용
--- 데이터 타입에는 Class 대신 구조체 사용
--- 즉시 해체할 때는 Dispose 수동 호출
--- 임시 객체들을 만들어내는 API들을 조심하라.
* C++ <-> C# 오버헤드
--- 객체의 변경 사항을 캐싱
--- 컴포넌트 참조를 캐싱
--- 빈 콜백 함수는 제거
2. 그래픽 최적화
* 텍스쳐 최적화
--- 권장 압축 사용하기 : 아이폰 -> PVRTC , 안드로이드(Tegra) -> DXT , 안드로이드(Adreno) -> ATC , 안드로이드(공통) -> ETC1 / ETC2
--- 텍스쳐 사이즈는 무조건 2의 제곱이어야 한다. POT(Power of Two) 아닐 경우 무조건 POT로 강제 변환함
--- 텍스쳐는 묶어서 사용하는게 이득이다. 한 화면에 나오는 것끼리~ 같은 재질의 오브젝트끼리~ 알파가 있는것과 없는것끼리
--- 32bit 텍스쳐보다는 16bit를 큰 텍스쳐로 쓰는게 이득이다.
--- 모바일뷰에서 가장 최적화된 해상도를 찾는데 주력한다. 이거저거 다해봐도 개개의 소스를 절약하는 방식이 최고임.
* 메쉬 최적화
--- Import시에 언제나 "Optimize Mesh" 사용 - 버텍스 캐쉬를 최적화 해준다.
--- 언제나 Optimize Mesh Data 옵션을 사용한다. 사용하지 않는 버텍스 정보들을 줄여준다.
--- 사용하지 않는 버텍스 정보들을 줄여 준다.
* 드로우 콜
--- 적절한 DP 는 100이하를 추천, 보통 70~100 정도가 일반적
* CULLING
---- 각 Layer 별로 컬링 거리를 설정해 준다. 중요도가 낮은 오브젝트의 컬링커리를 짧게 설정한다.
---- 오클루젼 컬링을 활용하여 카메라 밖은 잘라내도록 한다.
* 오브젝트 통합
---- 성질이 동일한 오브젝트들은 하나의 메쉬와 재질을 사용하도록 통합
*Batch
---- 스태틱 배치와 다이내믹 배치의 적절한 조합
* 라이팅
---- 라이트맵과 라이트렌더 모드 활용
* OverDraw
--- 한 픽셀에 두 번 이상 그리게 되는 경우 OVERDRAW 문제가 발생한다.
--- 기본적으로 앞에서 뒤로 그린다. Depth testing으로 인해서 오버드로우를 방지한다. 알파 블렌딩이 있을경우 소팅 문제 발생
--- 반투명 오브젝트의 개수의 제한을 건다. 뒤에서 앞으로 그려야 함. 반투명 오브젝트 갯수가 늘어날수록 퍼포먼스 직결~!
3. 사운드 최적화
--- 모바일에서 스테레오 사용은 퍼포먼스에 큰 영향을 끼친다. -> 되도록이면 모두 92 kb, 모노로 인코딩
--- 사운드 파일을 임포트하면 디폴트로 3D 사운드로 설정 -> 2D 사운드로 변경
--- 압축 사운드(mp3. ogg) , 비압축 사운드(wav) 구별. 압축 사운드-> 순간적인 효과음, 이펙트등.. 비압축사운드 -> 배경 음악
4. 폰트 리소스 최적화
--- Packed Font - R,G,B,A channel에 각각 글자의 형태를 저장하는 방법. 메모리 용량을 1/4로 절약
--- 리소스 기타 - ResourceLoadAsync() 함수는 엄청 느리다.
5. 셰이더 최적화
--- 기본 셰이더를 사용할 경우, 모바일용 셰이더 사용 Movile -> VertexLit 가장 빠른 셰이더
--- pow, exp, log, cos, sin, tan 같은 수학 함수들은 고비용이다.
--- 텍스쳐 룩 업 테이블을 만들어서 사용하는 것도 좋다.
--- 알파 테스트 연산(discard)은 느리다. 무조건 최소로..
--- 라이트맵 활용은 필수.
* 실수 연산
--- float : 32bit -> 버텍스 변환에 사용, 아주 느린 성능 (픽셀 셰이더에서 사용은 피함)
--- Half : 16bit -> 텍스쳐 uv에 적합, 대략 2배 빠름
--- fixed : 10bit -> 컬러, 라이트 계산과 같은 고성능 연산에 적합, 대략 4배 빠름]
6. 물리 엔진 최적화
--- FixedUpdate()는 Updata와 별도로 주기적으로 불리며, 주로 물리 엔진 처리
--- Default는 0.02초, 게임에 따라 0.2초 정도로 수정해도 문제 없음
--- 물리 엔진이 적용되지 않는 오브젝트는 Static으로 설정
--- 리지드 바디가 없는 고정 충돌체를 움직이면, CPU 부하 발생 - 물리 월드 재구성 - 이럴경우 isKinematic 옵션 사용
--- Maximum Allowed timestep 조정하여 물리 계산을 건너뛸 수 있는 부분은 무조건 건너 뛴다.
--- EDIT -> Project Setting -> Physics 에서 Solver Iteration Count 조정. 높을수록 정교하므로 낮게 설정한다.
--- Sleep 조절 -> 리지드 바디의 속력이 설정된 값보다 작을 경우, 휴면상태에 들어감.
--- Physics.Sleep() 함수를 이용하면, 강제 휴면 상태로 만듬.
--- 래그돌 사용 최소화
--- 태그 대신 레이어 활용 - 물리처리에서 레이어가 훨씬 유리, 성능과 메모리에서 장점을 가진다.
--- 메쉬 콜리더는 절대 사용 금지.
--- 레이캐스와 Sphere Check 같은 충돌 감지 요소를 최소화
--- Tilemap Collision Mesh -- 2D 게임에서 타일맵의 Collison Mesh를 최적화 하라.