Other UI Optimization Techniques and Tips – 번역
Other UI Optimization Techniques and Tips
– 원문 링크 –
Other UI Optimization Techniques and Tips
확인 완료한 버전: 5.3 – 난이도: 고급
특정 UI를 최적화할때 뚜렷한 방법이 없는 경우가 있습니다. 이 글은 이런 경우에 UI 성능을 향상시키는데 도움이될 수 있는 몇가지 방법에 대한 내용이 포함되어 있습니다. 하지만 이런 방법은 구조적인 “불명확성” 때문에, 관리가 어려워지거나 다른 부작용이 발생할 수 있습니다. 또한 다른 방법들은 초기 개발을 단순화시키는 목적으로 UI를 구성할 수 있지만, 이 경우 성능 문제가 쉽게발생할 수 있습니다.
RectTransform-기반 레이아웃 (RectTransform-based Layouts)
Layout 컴포넌트는 자식 계층의 UI 요소들이 dirty 상태로 표시될 때마다 이 UI 요소(자식 계층의 UI)들의 위치와 크기를 다시 계산해야하기 때문에 상대적으로 비용이 많이 듭니다. (자세한 내용은 Fundamentals 챕터의 Graphic rebuild 섹션을 참고하시기 바랍니다.) 특정 Layout 내에 있는 UI 요소의 수가 상대적으로 작고 그 수가 고정되어 있으며, Layout의 구조가 간단한 경우, 이 Layout을 RectTransform-기반 레이아웃으로 대체할 수 있습니다.
RectTransform에 앵커(anchor)를 할당해서, 부모 계층의 정보를 기반으로 RectTransform의 위치와 크기를 설정할 수 있습니다. 예를 들어, 두 개의 열을 가진 레이아웃은 다음과 같이 두 개의 RectTransform으로 구성할 수 있습니다:
- 왼쪽 열 앵커 X:(0, 0.5), Y:(0, 1)
- 오른쪽 열 앵커 X:(0.5, 1), Y:(0, 1)
RectTransform의 크기와 위치에 대한 계산은 트랜스폼(Transform) 시스템 자체의 네이티브 코드에서 처리됩니다. 일반적으로 이 방식이 Layout 시스템에 의존하는 방식보다 성능이 좋습니다. 스크립트를 이용해서 RectTransform-기반 레이아웃을 설정하는 것 역시 가능합니다. 하지만, 상대적으로 복잡하고 이 글의 범위를 벗어나기 때문에 다루지는 않겠습니다.
캔버스 렌더러 비활성화하기 (Disabling Canvas Renderers)
UI에서 분리된 부분을 화면에 보이거나 숨길때, 해당 UI의 루트 게임오브젝트를 활성화/비활성화하는 방법이 일반적으로 사용됩니다. 이렇게하면 비활성화 상태의 UI 컴포넌트에서는 입력이나 유니티 콜백(callback)을 처리하지 않습니다.
하지만, 이렇게하면 캔버스에서 VBO 데이터를 삭제합니다. 캔버스를 다시 활성화하게되면, 해당 캔버스(그리고 하위 캔버스에서 모두)에서 리빌드(rebuild)와 리배치(rebatch) 프로세스를 실행해야 합니다. 이 과정이 자주 발생하면 CPU 사용량의 증가로인해 프로그램의 프레임(frame rate)이 떨어질 수 있습니다.
이를 우회할 수 있는 한가지 방법은 해당 UI를 캔버스 또는 하위 캔버스에 표시하는 용도의 UI와 숨김 용도의 UI를 위치시킨 다음, 해당 캔버스 또는 하위 캔버스에 추가되어있는 Canvas Renderer 컴포넌트를 활성화/비활성화시키는 방법입니다.
이 방법을 사용하면 UI 메쉬를 그리지는 않지만, 메모리에는 유지되기 때문에 배칭(batching)이 보존됩니다. 또한, UI에서 OnEnable, OnDisable 콜백 메소드가 호출되지 않습니다.
그러나, 이 방법을 사용한다고해서 UI의 Graphics를 GraphicRegistry에서 제거하지 않기때문에 Graphic Raycast를 확인하기 위한 목록에는 여전히 남아있게 됩니다. 또한 숨김 용도의 UI 내에서 MonoBehaviour를 비활성화하지 않기 때문에 MonoBehaviour의 Update와 같은 유니티 라이프 사이클 콜백 메소드를 호출하게 됩니다.
이 문제를 해결하기 위해서는 이런 방식으로 비활성화되는 UI의 MonoBehaviour가 유니티의 라이프 사이클 콜백 메소드를 직접 구현하는대신, UI의 루트 게임오브젝트에 “콜백 관리자(Callback Manager)” MonoBehaviour를 추가한다음, 이 콜백 관리자에서 처리하도록 해야합니다. 이 “콜백 관리자”는 UI가 화면에 표시되거나 숨겨질 때마다 이를 알릴 수 있기 때문에, 유니티의 라이프 사이클 이벤트를 필요에 따라서 다른 곳에 전달하거나 전달하지 않도록 처리할 수 있습니다. “콜백 관리자” 패턴에 대한 자세한 내용은 이 글의 범위를 벗어나기 때문에 다루지 않습니다.
이벤트 카메라 할당하기 (Assigning Event Cameras)
유니티의 내장된 입력 관리자와 카메라 모드에서 World Space 또는 Screen Space로 설정된 캔버스를 함께 사용하는 경우에는 항상 Event Camera 또는 Render Camera 속성을 각각 설정하는 것이 중요합니다. 스크립트에서는 이 속성이 항상 worldCamera 속성으로 노출됩니다.
이 속성이 설정되지 않은 경우, 유니티 UI는 Main Camera 태그가 설정된 게임오브젝트에 연결된 Camera 컴포넌트의 검색을 통해서 메인 카메라를 찾습니다. 이 검색은 World Space 또는 Camera Space 캔버스 당 적어도 한 번씩 발생합니다. GameObject.FindWithTag의 속도가 느리기 때문에, 초기에 설정할 때나 UI 디자인을 할 때 모든 World Space 및 Camera Space 캔버스마다 Camera 속성을 할당할 것을 권장합니다.
이 문제는 Overlay 캔버스에서는 발생하지 않습니다.
내용 끝까지 읽어주셔서 감사합니다.
배너 클릭은 저에게 많은 힘이 됩니다.
감사합니다 🙂