이 가이드는 Unity 로컬라이제이션 설정 및 구성을 다룹니다. 로케일, 문자열 및 에셋 테이블, Addressables 통합, 에셋 테이블을 통한 CJK 폰트 지원을 포함합니다.
0. 패키지 설치 확인
다른 작업을 수행하기 전에, 먼저 Localization 패키지가 설치되었는지 확인합니다. 이 스킬의 많은 API는 패키지가 없으면 조용히 실패하거나 이해하기 어려운 오류를 발생시킵니다.
- 프로젝트를 읽어서 확인하고, 패키지 매니저에 묻지 마십시오.
Packages/packages-lock.json에서com.unity.localization을 찾으십시오. 이 파일은 Unity가 실제로 해결한 내용을 기록하며, 일반 JSON이고, 편집기나 비동기 호출 없이 읽을 수 있습니다. (Packages/manifest.json은 요청된 내용만 기록하므로, lock 파일을 확인하십시오.) - 없으면 설치:
UnityEditor.PackageManager.Client.Add("com.unity.localization"). - 적절히 대기하십시오.
Client.Add와Client.List는 비동기적입니다. 호출이 반환될 때 요청은 여전히InProgress상태이므로, 같은 구문에서 결과를 읽는 것은 아무 소용이 없습니다.IsCompleted를 폴링(busy-wait)하지 마십시오. 이는 실행 중인 메인 스레드를 차단합니다. 대신 설치를 실행한 후 반환하고, 나중 호출에서packages-lock.json을 폴링하여 ID가 나타날 때까지 기다리십시오. 설치 시 도메인 리로드도 발생하므로, 처음 한두 번의 폴링은 실패할 수 있습니다. 새로 설치는 보통 몇 초 안에 완료됩니다. - 어셈블리를 사용하기 전에 실제로 로드되었는지 확인하십시오. lock 파일이 어셈블리 준비 전에 작성될 수 있기 때문입니다:
var t = System.Type.GetType( "UnityEngine.Localization.Settings.LocalizationSettings, Unity.Localization"); return t != null ? "ready" : "not loaded yet";ready가 반환될 때만 진행하십시오.
1. 로컬라이제이션 설정 및 로케일
LocalizationEditorSettings.ActiveLocalizationSettings가 null이면, 찾거나 생성해야 합니다:
- 찾기:
AssetDatabase.FindAssets("t:LocalizationSettings", new[] { "Assets" })를 사용합니다. 찾으면 첫 번째 것을 로드하여LocalizationEditorSettings.ActiveLocalizationSettings에 할당합니다.- 항상 검색 폴더를 전달하십시오. 범위가 없는
FindAssets는 읽기 전용 패키지를 포함한 전체 프로젝트를 검색하므로, 패키지의 에셋을 반환하여 편집할 수 없는 대상을 가리킬 수 있습니다. 이는 이 스킬의 모든FindAssets호출에 적용됩니다.
- 항상 검색 폴더를 전달하십시오. 범위가 없는
- 생성: 찾지 못하면 새 인스턴스를 생성하고
Assets/Localization/LocalizationSettings.asset에 저장합니다.ScriptableObject.CreateInstance<LocalizationSettings>()다음에AssetDatabase.CreateAsset()를 사용합니다. - 활성화:
LocalizationEditorSettings.ActiveLocalizationSettings = settings를 설정합니다. - 로케일: 로케일(en, fr, de 등)이 있는지 확인합니다. 없으면 생성하고
LocalizationEditorSettings.AddLocale(locale)을 사용하여 설정에 추가합니다.
2. 로컬라이제이션 테이블 수정
문자열 또는 에셋 테이블을 프로그래밍 방식으로 변경하려면 편집기에 알려야 합니다. 필요한 에셋 테이블이 프로젝트에 이미 존재하지 않는 한, 항상 생성하십시오.
안전한 채우기 패턴
데이터셋에서 테이블을 채울 때, Locale.Identifier.Code로 명시적으로 일치시킵니다. GetLocales()의 순서는 입력 데이터 배열과 일치한다고 보장되지 않습니다. 순서에 의존하면 디버깅이 매우 어려운 조용한 데이터 불일치가 발생합니다.
에셋 테이블의 경우, 에셋의 GUID를 사용합니다: table.GetEntry(sharedId) ?? table.AddEntry(sharedId, guid);.
새로 고침 및 알림
키를 추가하거나 값을 업데이트한 후에는 편집기에 내부 상태를 새로 고칠 수 있도록 알립니다. 이 단계를 건너뛰면 편집기가 다음 재임포트까지 오래된 데이터를 표시합니다.
- 각 수정된
Table에 대해EditorUtility.SetDirty(collection),EditorUtility.SetDirty(collection.SharedData)를 호출합니다. - Unity 6+ 알림:
LocalizationEditorSettings.EditorEvents.RaiseCollectionModified(sender, collection); - 마지막에 항상
AssetDatabase.SaveAssets()를 호출합니다.
3. UI 로컬라이제이션 및 레이아웃
네임스페이스 및 충돌
- 항상 이름을 완전히 지정하십시오:
UnityEngine.UI.Image,UnityEngine.UI.VerticalLayoutGroup,UnityEngine.UI.ScrollRect,UnityEngine.UI.Mask,UnityEngine.UI.CanvasScaler,UnityEngine.UI.GraphicRaycaster,UnityEngine.UI.ContentSizeFitter,UnityEngine.UI.LayoutRebuilder등을 사용하십시오. UnityEngine.UI는 네임스페이스이자 클래스 컨테이너이므로, 완전히 지정되지 않은 이름은CS0118(네임스페이스를 타입처럼 사용)을 발생시킵니다. 완전한 이름 지정으로 이를 완전히 피할 수 있습니다.- 단일 인스턴스: 항상
GameObject.Find("YourCanvasName")으로 확인하고, 새로 만들기 전에 기존 것을 파괴하십시오. - 로케일 전환: 패키지를 사용하고, 미리보기와 런타임을 분리하십시오. 이 두 가지는 서로 다른 메커니즘입니다. 이를 혼동하는 것이 로케일 전환을 수동으로 구현하는 경우가 많은 이유입니다.
- 작성 중 로케일 미리보기는 Localization Scene Controls 창(
Window > Asset Management > Localization Scene Controls)을 사용하십시오. 이는 편집기 전용입니다. 런타임 기능이 아니므로, 게임 자체에 언어 설정이 필요할 때는 답이 아닙니다. - 런타임에 로케일 전환은
LocalizationSettings.SelectedLocale을 할당하십시오. 이것이 지원되는 진입점이며,LocalizeStringEvent를 통해 바인딩된 모든 것이 여기서 업데이트됩니다. - 게임이 시작되는 로케일을 고정하려면 Localization Settings 에셋에서 시작 로케일 선택기를 구성하십시오.
SpecificLocaleSelector는 선택한 로케일을 강제하는 것입니다. 기본 체인은 그렇지 않으면 시스템 언어를 선택합니다. - 절대 로케일 상태를 수동으로 관리하지 마십시오. 실제 게임 내 언어 메뉴는
SelectedLocale을 설정하고 패키지가 변경 사항을 전파하도록 하는 한 괜찮고 예상됩니다. 금지된 것은 자체적인 "현재 언어" 변수를 추적하고, 문자열을 자체적으로 교체하거나, 패키지를 우회하는 디버그 드롭다운이나 메뉴입니다. 프로젝트의 다른 어떤 것도 이를 따르지 않기 때문입니다.
- 작성 중 로케일 미리보기는 Localization Scene Controls 창(
지역화된 문자열 이벤트 (강력한 바인딩)
-
컴포넌트 유형 확인: 대상이
TextMeshPro인지 이전UnityEngine.UI.Text인지 식별합니다. -
올바르게 바인딩: 공개된
UnityEngine.Localization.Components.LocalizeStringEvent컴포넌트를 추가하고 직접 연결하십시오.StringReference를 테이블 항목으로 설정한 다음,OnUpdateString리스너를 추가하여 텍스트 컴포넌트에 값을 할당합니다(TMP_Text.textfor TextMeshPro,UnityEngine.UI.Text.textfor legacy Text).UnityEditor.Localization.Plugins.TMPro.LocalizeComponent_TMPro또는 그 UGUI 대응 항목을 리플렉션하지 마십시오. 이들은 (Localization 1.5.12 기준)internal이므로, 접근 제어를 우회하여 Unity가 안정성을 약속하지 않는 API에 도달하게 됩니다. 이는 패키지 릴리스에서 변경되거나 사라질 수 있습니다.LocalizeStringEvent는 공개되어 있으며, 명시적인 연결로 동일한 작업을 수행합니다. -
레이아웃 재구축: 지역화된 텍스트를 설정하거나 목록을 채운 후,
UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(parentTransform)를 호출하여 치수가 업데이트되도록 합니다.
4. 아시아 언어 폰트 지원 (CJK)
CJK 로케일에는 TMP 폴백 폰트를 피하십시오. 각 로케일별로 에셋 테이블 폰트 교체를 사용하십시오. 폴백은 글리프가 누락될 때 신뢰할 수 없고 디버깅하기 어렵습니다.
전제 조건: TMP Essential Resources를 임포트해야 함
TMP API를 건드리기 전에 이를 확인하십시오. 한 번도 임포트한 적 없는 프로젝트에서 TMP_Settings.instance는 null이고, TMP 호출은 유용한 정보를 제공하지 않는 NullReferenceException으로 실패합니다. TMP_FontAsset.CreateFontAsset가 그중 하나이므로, 폰트 생성은 첫 줄에서 오류와 함께 중단됩니다.