Layout Group 은 칸을 먼저 나누고 그 안에 자식을 놓는다
Figma 에서 버튼 셋을 Auto Layout 으로 가로로 묶었습니다. 간격은 12, 버튼은 글자에 맞춰 줄어듭니다.
Unity 에서 같은 버튼 셋에 Horizontal Layout Group 을 붙이면 모양이 다르게 나옵니다. 버튼 사이가 제멋대로 벌어지기도 하고, 버튼이 부모를 꽉 채우도록 늘어나기도 합니다.
체크박스 두 개 때문입니다. 이름만 봐서는 무엇을 하는지 짐작하기 어려운 두 칸이 버튼 줄을 네 가지 모양으로 바꿉니다.
그룹을 붙이면 자식의 자리는 그룹이 정한다
Layout Group 은 셋입니다. Horizontal 은 가로 한 줄, Vertical 은 세로 한 줄, Grid 는 격자입니다. 가로와 세로는 방향만 다르고 설정이 같아서, 이 글은 Horizontal 로 봅니다.
그룹을 붙이는 순간 자식의 RectTransform 일부가 회색으로 잠깁니다.
그룹의 설정은 이렇게 생겼습니다.
1 부터 3 까지는 Figma 에서 쓰던 그대로입니다. 문제는 5 와 7 입니다. 두 칸을 이해하려면 먼저 자식이 그룹에게 무엇을 알려 주는지 알아야 합니다.
자식은 크기 셋을 알려 준다
그룹은 자식에게 “얼마나 커야 하니” 를 세 가지로 묻습니다.
| 값 | 뜻 | 따로 안 정하면 |
|---|---|---|
| Min | 이보다 작아지지 않는 크기 | 대부분 0 |
| Preferred | 공간이 되면 갖고 싶은 크기 | 텍스트는 글자 폭, Simple 이미지는 원본 크기 |
| Flexible | 그러고도 남는 공간을 나눠 받는 비율 | 0 (안 받음) |
값을 직접 정하고 싶으면 자식에 Layout Element 를 붙입니다. 칸 앞의 체크박스를 켠 값만 쓰이고, 켠 값이 텍스트나 이미지가 알려 주는 값을 이깁니다.
그룹은 이 셋을 순서대로 나눠 줍니다.
- 공간이 모자라면 Min 과 Preferred 사이에서 같은 비율로 줄입니다. Min 보다는 작아지지 않습니다
- Preferred 합만큼 되면 모두 Preferred 입니다
- 남으면 Flexible 비율대로 나눕니다. Flexible 이 0 인 A 는 100 에서 멈추고 B 가 남는 공간을 전부 가져갑니다
Unity 6.6 부터는 Layout Element 에 Max Width, Max Height 도 생겼습니다. 그보다 앞선 버전에는 최대 크기를 정하는 칸이 없습니다.
두 체크박스가 만드는 네 가지 모양
이제 5 번 Control Child Size 와 7 번 Child Force Expand 를 봅니다.
Control Child Size 는 “그룹이 자식 크기까지 정할까” 입니다.
- 끄면 자식은 자기 RectTransform 의 Width 를 그대로 갖습니다. 그룹은 위치만 정합니다
- 켜면 그룹이 앞에서 본 Min, Preferred, Flexible 로 크기를 정합니다
Child Force Expand 는 “남는 공간을 자식마다 나눠 줄까” 입니다. 정확히는 모든 자식의 Flexible 을 최소 1 로 올립니다.
여기서 헷갈리는 자리가 나옵니다. 그룹이 나눠 주는 것은 칸 입니다. Control Child Size 가 꺼져 있으면 그룹은 자식 크기를 못 건드리니, 칸만 넓어지고 버튼은 그대로 입니다. 버튼은 넓어진 칸 안에서 Child Alignment 대로 놓이고, 그래서 버튼 사이가 벌어집니다. 처음에 본 “버튼 사이가 제멋대로 벌어진다” 가 바로 오른쪽 위 모양입니다.
직접 켜고 꺼 보면 더 분명합니다. 부모 너비를 바꾸면 공간이 모자랄 때와 남을 때도 볼 수 있습니다.
Figma Auto Layout 에서 넘어올 때
Padding, Gap, 정렬은 이름만 다르고 그대로 옮겨집니다.
달라지는 것은 자식 크기입니다. Figma 는 자식마다 W 를 Hug, Fixed, Fill 중에서 고릅니다. Unity 의 Control Child Size 와 Child Force Expand 는 그룹에 붙어 있어서 모든 자식에 한꺼번에 걸립니다. 그래서 자식마다 다르게 하려면 순서를 이렇게 잡습니다.
- 그룹에서 Control Child Size 는 켜고, Child Force Expand 는 끕니다. 이러면 모든 자식이 Hug 로 시작합니다
- Fixed 나 Fill 이어야 하는 자식에만 Layout Element 를 붙여 바꿉니다
Child Force Expand 를 켜 두면 모든 자식의 Flexible 이 1 이상이 되어, Fixed 로 둔 자식까지 늘어납니다. 섞어 쓰려면 꺼 둬야 합니다. 아래 그림은 모두 이 설정에서 출발합니다.
Hug: 글자에 맞춰 줄어들기
부모 그룹의 Control Child Size 가 켜져 있으면 버튼 폭은 버튼의 Preferred 가 됩니다.
여기서 한 번 더 걸리는 곳이 있습니다. 버튼 오브젝트는 이미지라서 Preferred 가 글자와 상관없는 값 입니다. 버튼이 글자에 맞추려면 버튼에도 Horizontal Layout Group 을 붙여서 Preferred 를 “글자 폭 + Padding” 으로 만들어야 합니다. Figma 에서 버튼 프레임에도 Auto Layout 을 거는 것과 같은 일입니다.
Fixed: 폭 고정
자식에 Layout Element 를 붙이고 Preferred Width 를 120 으로 둡니다.
Min Width 도 120 으로 같이 둡니다. 앞에서 본 대로 공간이 모자라면 그룹은 Min 과 Preferred 사이에서 줄이니, Preferred 만 두면 좁은 화면에서 줄어듭니다. Figma 의 Fixed 는 줄지 않으니 둘을 같게 둬야 같은 뜻이 됩니다.
부모 그룹의 Control Child Size 를 끄는 방법도 있지만, 그러면 모든 자식 이 자기 RectTransform 의 Width 를 쓰게 되어 Hug 나 Fill 과 섞을 수 없습니다.
Fill: 남는 공간 채우기
자식에 Layout Element 를 붙이고 Flexible Width 를 1 로 둡니다.
- Flexible 은 비율 입니다. 둘 다 Preferred 80 에서 출발하고, 남는 416 을 1 : 2 로 나눠 A 는 219, B 는 357 이 됩니다
- 모든 자식이 Fill 이면 그룹의 Child Force Expand 를 켜는 것과 같습니다
섞어 쓰기: 검색 바
실제 화면은 대부분 이렇게 섞여 있습니다. 설정은 위 셋을 자식마다 붙인 것뿐입니다. 최대 폭이 필요하면 Unity 6.6 부터 Layout Element 의 Max Width 를 씁니다.
Absolute position: Ignore Layout
Figma 에서 Auto Layout 안의 한 요소만 Absolute position 으로 빼면 흐름에서 빠지고 자유롭게 놓입니다. Unity 에서는 그 자식의 Layout Element 에서 Ignore Layout 을 켭니다.
선택된 탭 아래를 따라다니는 밑줄, 버튼 모서리에 겹치는 알림 점처럼 줄에 끼면 안 되는 장식 에 씁니다.
Gap 의 Auto 는 똑같이 만들 수 없다
Figma 의 Gap 을 Auto 로 두면 양끝 요소가 가장자리에 붙고 사이만 벌어집니다. Unity 에는 같은 설정이 없습니다.
양끝을 꼭 붙여야 하면 가장 왼쪽과 가장 오른쪽 요소를 그룹 밖으로 빼서 앵커로 모서리에 붙이는 편이 정확합니다.
크기가 다른 요소의 줄바꿈은 없다
Figma 의 Wrap 은 폭이 제각각인 요소를 줄바꿈하며 채웁니다. Unity 기본 컴포넌트에는 이것이 없습니다.
태그 목록처럼 폭이 다른 요소를 줄바꿈해야 하면 프로그래머가 따로 만들어야 합니다. 시안에서 Wrap 을 썼다면 미리 알려 주세요.
글에 맞춰 커지는 박스: Content Size Fitter
Layout Group 은 자식을 배치할 뿐, 자기 크기는 바꾸지 않습니다. 자기 크기를 내용에 맞추는 것이 Content Size Fitter 입니다. 가로와 세로를 따로 고릅니다.
| Fit | 하는 일 |
|---|---|
| Unconstrained | 크기를 건드리지 않습니다 |
| Min Size | Min 크기로 맞춥니다 |
| Preferred Size | Preferred 크기로 맞춥니다. 거의 이것을 씁니다 |
캐릭터 머리 위 말풍선이 대표적인 예입니다. 말풍선 이미지에 Horizontal Layout Group 과 Content Size Fitter 를 같이 붙이고, 안에 글자를 넣습니다. 그룹의 Preferred 는 글자 폭에 Padding 을 더한 값 이라, Content Size Fitter 가 말풍선을 딱 그만큼으로 맞춥니다.
- 커지는 방향은 피벗이 정합니다. 앞에서 본 대로 크기는 피벗을 중심으로 바뀝니다. 말풍선은 꼬리가 캐릭터에 붙어 있어야 하니 피벗을 꼬리 쪽 모서리에 둡니다
- Unity 6.6 부터는 Preferred Size 가 Layout Element 의 Max Width 를 넘지 않습니다. 그래서 넓어지다가 최대 폭에서 멈추고 줄바꿈되는 말풍선을 설정만으로 만들 수 있습니다. 같은 버전에 Clamped 모드도 생겼는데, 크기를 직접 정하지 않고 Min 과 Max 사이를 벗어나지 않게만 막습니다
Layout Group 의 자식에는 Content Size Fitter 를 붙이지 않습니다. 자식 크기는 부모 그룹이 정하는 자리라 둘이 같은 값을 두고 싸우고, Unity 도 경고를 띄웁니다. (“A child of a layout group should not have a Content Size Fitter component, since it should be driven by the layout group.”) 자식을 내용에 맞추고 싶으면 부모 그룹의 Control Child Size 를 켭니다.
시안을 넘길 때 적어 주면 좋은 것
| 적어 줄 것 | 무엇이 정해지나 |
|---|---|
| 줄의 방향, 간격, 안쪽 여백 | Layout Group 종류, Spacing, Padding |
| 요소가 글에 맞춰 줄어드는지(Hug), 줄을 꽉 채우는지(Fill), 고정 폭인지 | Control Child Size, Child Force Expand, Layout Element |
| 남는 공간이 생기면 어느 쪽으로 붙는지 | Child Alignment |
| 늘어나는 요소의 최소, 최대 폭 | Layout Element 의 Min Width, Max Width |
| 글이 길어질 때 박스가 어느 방향으로 커지는지 | Content Size Fitter, 피벗 |
Figma 에서 Auto Layout 의 Hug, Fill, Fixed 를 정확히 걸어 두면 위 표의 두 번째 줄은 대부분 전달됩니다.
정리
- Layout Group 을 붙이면 자식의 위치(와 켜면 크기)를 그룹이 정합니다. 자식의 RectTransform 은 회색으로 잠깁니다
- 자식은 Min, Preferred, Flexible 을 알려 주고, 그룹은 이 순서대로 공간을 나눕니다
- Control Child Size 는 그룹이 자식 크기까지 정할지, Child Force Expand 는 남는 공간을 자식마다 나눠 줄지입니다
- 그룹이 나눠 주는 것은 칸 입니다. Control Child Size 가 꺼진 채 Force Expand 만 켜면 칸만 넓어져 버튼 사이가 벌어집니다
- Figma 처럼 자식마다 Hug, Fixed, Fill 을 다르게 하려면 그룹은 Control 켬, Expand 끔으로 두고 자식마다 Layout Element 로 정합니다. Fixed 는 Min 과 Preferred 를 같게, Fill 은 Flexible 1
- 내용에 맞춰 자기 크기 를 바꾸는 것은 Content Size Fitter 이고, 커지는 방향은 피벗이 정합니다. Layout Group 의 자식에는 붙이지 않습니다