Cheondi
개발 · Unity

언어를 바꾸자 팝업 정렬이 무너졌다

실행 중 언어 변경 뒤 팝업 크기와 정렬이 어긋나는 문제를 레이아웃 갱신 순서로 해결한 기록입니다.

  • #unity
  • #localization
  • #layout

설정에서 언어를 바꾸면 화면 문구는 바로 변경됐지만 팝업 버튼이 겹치거나 제목이 잘리는 문제가 생겼다. 앱을 다시 실행하면 정상이라 번역 데이터 문제는 아니었다. 문자열은 바뀌었는데 레이아웃은 이전 언어의 크기를 기준으로 계산된 상태였다.

특히 짧은 문구에서 긴 문구로 바꿀 때 잘 보였다. 텍스트 변경과 레이아웃 계산이 같은 프레임에서 어떤 순서로 일어나는지가 중요했다.

언어 변경을 단순 문자열 교체로 보지 않았다

언어 이벤트를 받은 각 Text가 따로 값을 바꾸고 끝내면 부모 레이아웃은 어느 시점에 다시 계산해야 하는지 몰랐다. 번역 적용과 레이아웃 갱신 단계를 나눴다.

IEnumerator ApplyLanguage(Language language)
{
    localization.Set(language);
    RefreshAllTexts();
    yield return null;
    Canvas.ForceUpdateCanvases();
    LayoutRebuilder.ForceRebuildLayoutImmediate(rootRect);
}

강제 재계산은 필요한 팝업 루트에만 적용해 전체 Canvas를 반복해서 갱신하지 않았다.

버튼은 글자 길이에 맞춰 늘어나야 했다

고정 너비 두 버튼은 짧은 언어에서는 괜찮았지만 긴 번역에서 겹쳤다. 최소 너비와 내부 여백을 정하고 공간이 부족하면 세로 배치로 바뀌게 했다.

가로 배치 가능: 버튼 최소 너비 + 간격 <= 팝업 내부 너비
공간 부족     : 세로 스택으로 전환
제목          : 최대 두 줄, 이후 말줄임

무조건 글자를 작게 만드는 자동 축소는 가독성을 해칠 수 있어 마지막 수단으로 두었다.

열려 있는 팝업도 다시 그렸다

언어 변경 시 새로 열 팝업만 바뀌고 이미 열린 팝업은 이전 문구를 유지하는 경우가 있었다. 화면마다 언어 이벤트를 직접 구독하게 하기보다 팝업 시스템이 현재 모델을 기준으로 표시 내용을 다시 바인딩했다.

팝업이 닫히는 중이거나 전환 애니메이션 중일 때는 중복 갱신하지 않도록 생명주기도 확인했다.

번역은 레이아웃 입력 데이터였다

다국어 대응을 텍스트 파일을 교체하는 작업으로만 봤었다. 실제로는 문자열 길이, 줄바꿈, 읽는 방향이 레이아웃의 입력이었다. 기준 언어 화면만 맞춰서는 충분하지 않았다.

이후 UI를 만들 때 가장 짧은 문구와 가장 긴 문구, 실행 중 언어 변경을 같이 시험한다. 번역 완료 여부뿐 아니라 그 데이터가 화면 구조에 들어왔을 때 버티는지도 확인하게 됐다.