[Unity] UGUI 최적화에 대한 기록
1. 중첩 Canvas
1.1 Canvas 안의 요소가 변경되면 Canvas 안의 모든 요소가 갱신된다.
1.2 Canvas가 중첩됐을 때 부모와 자식 Canvas 사이에는 서로 영향을 주지 않는다. (부모 Canvas의 크기가 변경되는 경우는 예외)
위의 두 가지 때문에 변경이 잦은 요소를 중첩된 Canvas 중 자식 Canvas에 두어 별도로 관리하면 성능이 향상될 가능성이 높다.
2. 계층의 깊이를 낮게 유지
UI의 RectTransform은 계층구조로 이루어져 있다. 때문에 계층의 깊이가 깊어질수록 Canvas 갱신 등의 비용이 커진다.
3. Re-parenting 주의
부모를 바꾸는 행위를 할 때 Canvas가 갱신될 가능성이 높기 때문에 자제하는 것이 좋다.
4. Pixel Perfect 사용 주의
Pixel Perfect를 사용하면 UI를 선명하고 또렷하게 만들 수 있다. 다만 해당 기능은 연산 비용이 크기 때문에 많이 사용하거나 Canvas 갱신이 자주 발생하게 되면 성능을 떨어뜨리는 원인이 될 수 있다.
5. Canvas 비활성화
Canvas를 비활성화할 때는 Canvas 컴포넌트를 비활성화해야 한다. 컴포넌트를 비활성화하면 Canvas가 표시되지는 않지만 Canvas의 Vertex 버퍼를 삭제하지 않고 모든 meshes와 vertices를 유지한다. 때문에 Canvas를 활성화시키면 가지고 있는 데이터를 기반으로 그린다. 그리고 컴포넌트를 비활성화했다면 Canvas 오브젝트를 비활성화하는 것이 아니기 때문에 OnDisable / OnEnable 콜백이 트리거되지 않기 때문에 프레임마다 실행되는 코드를 가지는 요소가 있으면 이를 비활성화해야 한다.
6. Graphic Raycaster와 Raycast Target
캔버스의 Graphic Raycaster 컴포넌트와 UI요소의 Raycast Target은 캔버스 내의 이벤트를 감지하기 위해 사용된다. 현재 Unity에서는 기본적으로 활성화된 상태인데, 필요하지 않은 요소는 비활성화하여 성능을 높일 수 있다.
7. Sprite Atlas 사용
여러 개의 이미지를 사용할 때 SpriteAtlas를 사용하여 Draw Call을 최소화한다.
8. RectTransform의 Z 값
Z 값이 달라지면 블랜딩 처리를 위해 그려지는 순서가 달라지기 때문에 Draw Call이 늘어날 가능성이 높다.
9. Layout Group 사용 최소화 Layout Group에 포함된 요소가 변경될 경우 변경된 요소와 해당 요소의 상위에 존재하는 모든 요소가 갱신되는데, 갱신되는 모든 요소는 최소 한 번은 GetComponent를 호출하며 GetComponent는 성능이 좋지 않기에 Layout Group 사용을 최소화하는 것이 좋다. 10. 애니메이터 사용 시 애니메이터는 애니메이션이 동작하지 않더라도 모든 프레임에서 Canvas를 갱신하게 된다.
만약 사용한다면 애니메이션을 코드로 작성하거나 Canvas를 나누어 담는 것도 방법이 될 수 있다.
11. 화면 전체를 UI로 사용할 때
화면 전체를 UI로 채우더라도 그 뒤에 존재하는 게임 오브젝트를 보이지 않더라도 랜더링된다. 이때 게임 오브젝트를 랜더링하는 카메라를 비활성화하여 랜더링하지 않게 한다.
또한 화면에 보이는 Canvas 이외의 Canvas가 있다면 해당 Canvas도 비활성화해 준다.
그리고 Application.targetFrameRate 값 또한 낮추어 성능을 향상시킬 수 있다.
12. UI 요소 숨기기
UI 요소를 숨길 때 알파값을 0으로 변경해도 여전히 Draw Call이 발생한다. 때문에 숨겨야 한다면 오브젝트 자체를 꺼준다.
최적화 방법 출처
https://unity3d.com/kr/how-to/unity-ui-optimization-tips
https://ilkinulas.github.io/development/unity/2016/05/19/unity_ui_performance_tips.html