가로모드를 붙이고 나니 같은 방향 안에서도 화면 크기에 따라 문제가 달랐다. 큰 기기에서는 여백이 과했고 작은 기기에서는 텍스트와 버튼이 겹쳤다. 기기마다 좌표를 따로 넣으면 당장은 맞출 수 있었지만 다음 해상도가 추가되면 다시 깨질 게 뻔했다.
그때부터 픽셀 위치보다 레이아웃 규칙을 먼저 찾아야 했다. 어떤 영역은 고정 크기여야 하고, 어떤 영역이 남는 공간을 가져가야 하는지 정리했다.
Anchor를 많이 쓰는 것과 잘 쓰는 건 달랐다
Anchor를 Stretch로 바꾸면 자동으로 반응형이 될 줄 알았다. 부모가 줄어들 때 자식이 지나치게 좁아지거나, Layout Group과 서로 다른 계산을 하면서 위치가 튀었다.
다음처럼 역할을 나누는 게 도움이 됐다.
상단 조작 영역 : 필요한 최소 높이 유지
목록 영역 : 남은 높이를 모두 사용
상세 패널 : 최대·최소 크기 안에서 비율 조정
터치 버튼 : 최소 입력 영역 유지
모든 것을 비율로 늘리지 않고 고정되어야 할 것과 유연해야 할 것을 구분했다.
최소 크기를 먼저 정했다
화면을 계속 줄이면 어느 순간 정보가 겹치는 건 피할 수 없다. 무한히 줄어드는 레이아웃을 만드는 대신 정상 사용이 가능한 최소 크기를 정하고 그 아래에서는 일부 상세를 접거나 스크롤하도록 했다.
float width = Mathf.Max(rect.rect.width, minWidth);
float itemWidth = width - sidePadding * 2;
코드로 강제하는 것만이 답은 아니지만, 컴포넌트가 계산을 수행한다면 입력 범위를 명확히 해야 했다.
긴 문구와 실제 데이터로 확인했다
짧은 한국어와 테스트 숫자로만 보면 잘 맞았다. 언어가 바뀌거나 금액 자릿수가 길어지면 텍스트가 버튼을 밀어냈다. 임시 문자열을 줄여서 맞추는 대신 가장 긴 문구, 큰 음수와 빈 값으로 시험했다.
Text 컴포넌트의 자동 축소도 무조건 켜지 않았다. 지나치게 작아져 읽을 수 없는 경우가 있었기 때문이다. 줄바꿈, 말줄임, 영역 확장 중 화면의 의미에 맞는 방식을 선택했다.
좌표 대신 제약을 생각하게 됐다
처음 UI를 수정할 때는 “이 버튼을 x만큼 옮긴다”는 식으로 접근했다. 여러 크기를 대응하면서 “이 버튼은 오른쪽 여백을 유지한다”, “목록은 남은 영역을 쓴다”처럼 관계를 생각하기 시작했다.
모든 해상도를 완벽히 예측할 수는 없었다. 대신 최소 크기, 긴 데이터, 방향 전환이라는 몇 가지 강한 조건에서 규칙이 깨지지 않는지 확인했다. 같은 UI를 여러 크기에서 살리는 일은 좌표를 많이 저장하는 게 아니라 변해도 지켜야 할 제약을 정하는 일이었다.