성능이 악랄하다는 Unity Auto Layout을 개조시키기 위해 공부중입니다.
-> 성능이 악랄한 이유: 레이아웃 요소 변경시마다 자식에 있던 모든 레이아웃 엘리먼트가 부모로 GetComponent를 호출하며 Layoutgroup 컴포넌트를 탐색하며 리빌딩 과정을 진행함
Rect Transform 레이아웃 시스템은 다양한 유형의 레이아웃을 처리할 수 있게 유연하며 요소를 자유롭게 배치할 수도 있습니다. 그러나 때로는 좀 더 구조화된 형태가 필요할 수 있습니다. 자동 레이아웃 시스템은 수평 그룹, 수직 그룹 또는 그리드와 같은 중첩된 레이아웃 그룹에 요소를 배치하는 방법을 제공합니다. 또한 포함된 콘텐츠에 따라 요소의 크기를 자동으로 조정할 수 있습니다. 예를 들어 버튼의 텍스트 내용에 약간의 패딩을 적용하여 정확한 사이즈로 동적으로 크기를 조정할 수 있습니다. 자동 레이아웃 시스템은 기본 Rect Transform 레이아웃 시스템 위에 구축된 시스템입니다. 일부 요소 또는 모든 요소에 선택적으로 사용할 수 있습니다.
레이아웃 요소 이해하기
자동 레이아웃 시스템은 레이아웃 요소와 레이아웃 컨트롤러의 개념을 기반으로 합니다. 레이아웃 요소는 Rect Transform 및 선택적으로 다른 구성 요소도 포함하는 게임 개체입니다. 레이아웃 요소는 어떤 크기를 가져야 하는지에 대한 특정 정보를 가지고 있습니다. 레이아웃 요소는 자체 크기를 직접 설정하지 않지만 레이아웃 컨트롤러로 작동하는 다른 구성 요소는 제공하는 정보를 사용하여 사용할 크기를 계산할 수 있습니다.
레이아웃 요소에는 다음을 정의하는 속성이 있습니다.
- 최소 너비(Minimum width)
- 최소 높이(Minimum height)
- 기본 너비(Preferred width)
- 기본 높이(Preferred height)
- 유연한 너비(Flexible width)
- 유연한 높이(Flexible height)
레이아웃 요소에서 제공하는 정보를 사용하는 레이아웃 컨트롤러 구성 요소의 예로는 Content Size Fitter와 Layout Group 컴포넌트가 있습니다. 레이아웃 그룹의 레이아웃 요소 크기 조정에 대한 기본 원칙은 다음과 같습니다.
- 첫 번째 최소 크기가 할당됩니다.
- 사용 가능한 공간이 충분하면 기본 크기가 할당됩니다.
- 사용 가능한 추가 공간이 있는 경우 유연한 크기가 할당됩니다.
Rect Transform이 있는 모든 게임 개체는 레이아웃 요소로 작동할 수 있습니다. 기본적으로 최소, 기본 및 유연한 크기는 0입니다. 특정 컴포넌트는 게임 개체에 추가될 때 이러한 레이아웃 속성을 변경합니다. image 및 Text 컴포넌트는 레이아웃 요소 속성을 제공하는 구성 요소의 두 가지 예입니다. 스프라이트 또는 텍스트 내용과 일치하도록 기본 너비와 높이를 변경합니다.
레이아웃 요소(Layout Element) 컴포넌트
최소, 기본 또는 유연한 크기를 재정의하려는 경우 게임 개체의 레이아웃 요소 컴포넌트를 추가하여 이를 수행할 수 있습니다. 레이아웃 요소 컴포넌트를 사용하면 하나 이상의 레이아웃 속성에 대한 값을 재정의할 수 있습니다. 재정의할 속성에 대한 확인란은 활성화한 다음 재정의할 값을 지정합니다.
레이아웃 컨트롤러에 대한 이해
레이아웃 컨트롤러는 하나 이상의 레이아웃 요소의 크기와 위치를 제어하는 구성 요소로, Rect Transforms가 활성화된 게임 개체를 의미합니다. 레이아웃 컨트롤러는 자체 레이아웃 요소(자체에 있는 것과 동일한 게임 오브젝트)를 제어하거나 자식 레이아웃 요소를 제어할 수 있습니다. 레이아웃 컨트롤러로 작동하는 컴포넌트는 레이아웃 요소로 작동할 수도 있습니다.
Content Size Fitter
Content Size Fitter는 자체 레이아웃 요소의 크기를 제어하는 레이아웃 컨트롤러 역할을 합니다. 자동 레이아웃 시스템이 작동하는지 확인하는 가장 간단한 방법은 Text 구성 요소가 있는 게임 개체에 Content Size Fitter 구성 요소를 추가하는 것입니다. 가로 맞춤 또는 세로 맞춤을 기본으로 설정하면 Rect Transform이 너비 및 높이를 텍스트 콘텐츠에 맞게 조정합니다.
-> 설정한 옵션에 따라 자식 오브젝트에 맞게 현재 오브젝트의 크기를 조정
Aspect Ratio FItter
Aspect Ratio Fitter는 자체 레이아웃 요소의 크기를 제어하는 레이아웃 컨트롤러 역할을 합니다. 너비에 맞게 높이를 조정하거나 그 반대의 경우도 마찬가지입니다. 또는 요소를 상위 요소 안에 맞추거나 상위 요소를 둘러쌀 수 있습니다. Aspect Ratio Fitter는 최소 크기 및 기본 크기와 같은 레이아웃 정보를 고려하지 않습니다.
Layout Group
레이아웃 그룹은 자식 레이아웃 요소의 크기와 위치를 제어하는 레이아웃 컨트롤러 역할을 합니다. 예를 들어 수평 레이아웃 그룹은 자식을 서로 옆에 배치하고 그리드 레이아웃 그룹은 자식을 그리드에 배치합니다. 레이아웃 그룹은 자체 크기를 제어하지 않습니다. 대신 다른 레이아웃 컨트롤러에 의해 제어되거나 수동으로 설정될 수 있는 레이아웃 요소 자체로 기능합니다.
레이아웃 그룹 간에 크기가 할당된다면, 대부분의 경우에 각각의 레이아웃 요소들은 최소, 기본, 유연한 크기를 바탕으로 공간에 적절한 공간을 할당하려고 시도할 것입니다. 레이아웃 그룹은 이러한 방식으로 중첩될 수 있습니다. 레이아웃 그룹에는 수평 레이아웃 그룹, 수직 레이아웃 그룹, 그리드 레이아웃 그룹이 있습니다.
Driven Rect Transform properties
자동 레이아웃 시스템의 레이아웃 컨트롤러는 특정 UI 요소의 크기와 위치를 자동으로 제어할 수 있으므로 이러한 크기와 위치는 Inspector또는 Scene View를 통해 수동으로 편집해서는 안됩니다. 이러한 변경된 값은 어쨌든 다음 레이아웃 계산에서 레이아웃 컨트롤러에 의해 재설정됩니다.
Rect Transform에는 이를 해결하기 위한 driven prorerties 개념이 있습니다. 예를 들어 Horizontal Fit 속성이 Minimum 또는 Preferred로 설정된 Content Size Fitter는 동일한 게임 개체에서 Rect Transform의 너비를 drive합니다. 너비는 읽기 전용으로 표시되고 Rect Transform 상단의 작은 정보 상자는 하나 이상의 속성이 Content Size Fitter에 의해 driven됨을 알려줍니다.
driven Rect Transforms 속성에는 수동 편집을 방지하는 것 외에 다른 이유가 있습니다. Game View의 해상도나 크기를 변경하는 것만으로 레이아웃을 변경할 수 있습니다. 이것은 차례로 레이아웃 요소의 크기나 배치를 변경하여 구동 속성의 값을 변경할 수 있습니다. 그러나 Game View의 크기가 조정되었다는 이유로 Scene에 저장되지 않은 변경 사항이 있는 것으로 표시되는 것은 바람직하지 않습니다. 이를 방지하기 위해 구동 속성의 값은 장면의 일부로 저장되지 않으며 해당 속성을 변경해도 장면이 변경된 것으로 표시되지 않습니다.
기술적 세부 사항
자동 레이아웃 시스템에는 특정 컴포넌트가 내장되어 있지만 사용자 정의 방식으로 레이아웃을 제어하는 새 구성 요소를 생성하는 것도 가능합니다. 이것은 컴포넌트가 자동 레이아웃 시스템에서 인식하는 특정 인터페이스를 구현하도록 함으로써 수행됩니다.
레이아웃 인터페이스
컴포넌트는 'ILayoutElement' 인터페이스를 구현하는 경우 자동 레이아웃 시스템에서 레이아웃 요소로 처리됩니다.
컴포넌트는 'ILayoutGroup' 인터페이스를 구현하는 경우 자식의 Rect Transforms를 drive해야 합니다.
컴포넌트는 'ILayoutSelfController' 인터페이스를 구현하는 경우 자체 RectTransform을 drive해야 합니다.
레이아웃 계산
자동 레이아웃 시스템은 다음의 순서로 레이아웃을 평가하고 실행됩니다.
1. 레이아웃 요소의 최소, 기본 및 유연한 너비는 ILayoutElement구성 요소에서 CalculateLayoutInputHorizontal을 호출하여 계산됩니다. 이것은 부모가 자신의 계산에서 자녀의 정보를 고려할 수 있도록 자녀가 부모보다 먼저 계산되는 상향식 순서로 수행됩니다.
2. 레이아웃 요소의 유효 너비는 ILayoutController 구성 요소에서 SetLayoutHorizontal을 호출하여 계산되고 설정됩니다. 이것은 자식 너비의 할당이 부모에서 사용 가능한 전체 너비를 기반으로 해야 하기 때문에 자식 너비가 부모 다음에 계산되는 하향식 순서로 수행됩니다. 이 단계 후에 레이아웃 요소의 RectTransforms는 새로운 너비를 같습니다.
3. 레이아웃 요소의 최소, 기본 및 유연한 높이는 ILayoutElement 구성 요소에서 CalculateLayoutInputVertical을 호출하여 계산됩니다. 이것은 부모가 자신의 계산에서 자녀의 정보를 고려할 수 있도록 자녀가 부모보다 먼저 계산되는 상향식 순서로 수행됩니다.
4. 레이아웃 요소의 유효 높이는 ILayoutController 구성 요소에서 SetLayoutVertical을 호출하여 계산되고 설정됩니다. 자식 높이 할당은 부모에서 사용할 수 있는 전체 높이를 기반으로 해야 하기 때문에 자식 높이가 부모 다음에 계산되는 하향식 순서로 수행됩니다. 이 단계 후에 레이아웃 요소의 Rect Transforms는 새로운 높이를 갖게 됩니다.
위에서 볼 수 있듯이 자동 레이아웃 시스템은 너비를 먼저 평가한 다음 높이를 평가합니다. 따라서 계산된 높이는 너비에 따라 달라질 수 있지만 계산된 너비는 높이에 따라 달라질 수 없습니다.
레이아웃 재구축 트리거
구성 요소의 속성이 변경되어 현재 레이아웃이 더 이상 유효하지 않은 경우 레이아웃 재계산이 필요합니다. 다음 호출을 사용하여 트리거할 수 있습니다.
LayoutRebuilder.MarkLayoutForRebuild (transform as RectTransform);
재구축은 즉시 발생하지 않고 현재 프레임이 끝날 때 렌더링이 발생하기 직전에 발생합니다. 즉각적이지 않은 이유는 레이아웃이 동일한 프레임 동안 여러 번 다시 빌드될 가능성이 있어 성능이 저하도리 수 있기 때문입니다.
재구축을 트리거해야 하는 경우에 대한 지침
- 레이아웃을 변경할 수 있는 속성에 대한 setter에서
- 이러한 콜백에서:
- OnEnable
- OnDisable
- OnRectTransformDimensionsChange
- OnValidate
- OnDidApplyAnimationProperties
'유니티 > UI System' 카테고리의 다른 글
[UGUI] Layout Element - Unity Auto Layout (0) | 2022.04.07 |
---|---|
[UIToolkit]UXML 템플릿 작성 - 1 (0) | 2022.03.30 |
[UIToolkit]UXML을 사용한 UI 구조 (0) | 2022.03.30 |
[UIToolkit]레이아웃 엔진 (0) | 2022.03.30 |
[UIToolkit]Visual Tree (0) | 2022.03.25 |