Skip to content

Commit 91837bc

Browse files
author
Unity Technologies
committed
com.unity.localization@1.5.10
## [1.5.10] - 2026-03-12 ### Fixed - Added missing `Serializable` attribute to `FormatterBase`. ([LOC-1282](https://issuetracker.unity3d.com/product/unity/issues/guid/LOC-1282)) - Added support for BCP 47 resource locale codes on Android 21+. (UUM-132466). ([UUM-132466](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-132466)) - Adjusted the localization tables window so only the search bar shrinks/expands and all other buttons remain fixed. (LOC-1278) - Changed the Table Key ID Field so it is a selectable label and can now be copied. (LOC-1305) - Disabled the horizontal scroll in the ReorderableListView component. It was occasionally appearing when unnecessary and should not be required. ([LOC-1287](https://issuetracker.unity3d.com/product/unity/issues/guid/LOC-1287)) - Fix the samples not being included in the package data. - Fixed alignment of Project Locale identifier field. ([LOC-1277](https://issuetracker.unity3d.com/product/unity/issues/guid/LOC-1277)) - Fixed an issue where nested LocalizedStrings could not have their local variables queried. ([UUM-134944](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-134944)) - Fixed an issue where the ExcludeEntryFromExport metadata would be ignored when exporting to CSV and XLIFF if the first table entry was null. ([UUM-136670](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-136670)) - Fixed Android using the wrong app name locale codes for Indonesian and Hebrew. (LOC-1272) - Fixed the wrong group being used to resolve assets when a SharedGroup was assigned to the GroupResolver. ([UUM-135659](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-135659)) - Fixed UI Builder picker so it saves the view state. - Improved fast enter playmode support. (UUM-131023) - Removed warning when using default localization settings. (LOC-1290) - When a new String Table is added, the IsSmart flag will now be propagated to its entries if it is already consistently set across all existing tables. ([LOC-1274](https://issuetracker.unity3d.com/product/unity/issues/guid/LOC-1274))
1 parent acb41bb commit 91837bc

31 files changed

+269
-42
lines changed

.attestation.p7m

30 Bytes
Binary file not shown.

.signature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"timestamp":1763031297,"signature":"H2E2KLx+fxaewrb/RnwpoPK11CUNM5zihKp4c5CO8cG+4Kdn7MPd2AjF/Gw4dJOQ/7OW21YUcFwD6riKxbAb5FYpXka/TwL2OeUidHg98L3LnhbQe0zCkC/FPJ5DoEQXI464DUnXP8sHO69PPLVS+CdIed4StkLkko401h2ThGrhokJzAgCR8fFdWZnp3f8eP0FXuJm6D8UuFcs3QCdhArfvKl9giXN1Se4TtpR7Ky5IqfhWI0Vh3Af7iNUO8XVb5Mrk7MkomOJETye+SeYTa93igBWEuIbjfbtssX8XBiR6tUdYUCv9ckdoFNteXmffO7sFXhLww2tNKNz51qpU6LHj0qtTJDDpuCFk4JtpVpcgZR9gp3xUdbnspsTj1kS369s28MTmP3gZKZ4I3AhlFYV852KR3QKN4x0lPUssY9fEaYVHl6xzoMShoxAGCa0wRbK41RgmAm341BJRAZP40Y/Bf9G0ULIVqtIlXqr9iQ/Pi+p3w6G/ALF+jiN13Vb+","publicKey":"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQm9qQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FZOEFNSUlCaWdLQ0FZRUFzdUhXYUhsZ0I1cVF4ZEJjTlJKSAordHR4SmoxcVY1NTdvMlZaRE1XaXhYRVBkRTBEMVFkT1JIRXNSS1RscmplUXlERU83ZlNQS0ZwZ1A3MU5TTnJCCkFHM2NFSU45aHNQVDhOVmllZmdWem5QTkVMenFkVmdEbFhpb2VpUnV6OERKWFgvblpmU1JWKytwbk9ySTRibG4KS0twelJlNW14OTc1SjhxZ1FvRktKT0NNRlpHdkJMR2MxSzZZaEIzOHJFODZCZzgzbUovWjBEYkVmQjBxZm13cgo2ZDVFUXFsd0E5Y3JZT1YyV1VpWXprSnBLNmJZNzRZNmM1TmpBcEFKeGNiaTFOaDlRVEhUcU44N0ZtMDF0R1ZwCjVNd1pXSWZuYVRUemEvTGZLelR5U0pka0tldEZMVGdkYXpMYlpzUEE2aHBSK0FJRTJhc0tLTi84UUk1N3UzU2cKL2xyMnZKS1IvU2l5eEN1Q20vQWJkYnJMbXk0WjlSdm1jMGdpclA4T0lLQWxBRWZ2TzV5Z2hSKy8vd1RpTFlzUQp1SllDM0V2UE16ZGdKUzdGR2FscnFLZzlPTCsxVzROY05yNWdveVdSUUJ0cktKaWlTZEJVWmVxb0RvSUY5NHpCCndGbzJJT1JFdXFqcU51M3diMWZIM3p1dGdtalFra3IxVjJhd3hmcExLWlROQWdNQkFBRT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg"}
1+
{"timestamp":1773313868,"signature":"PJOWuPoqR1YXxcWgTiSx0J40PaYx00X9Kq6i6K00bfrydRRg/YeTAAkmzJk/XRNGQdtb4J5dzdETJQnp2HlRr/SFKRYW1zI/Aqd+pgGLUXiXA3LV8YHSocphH3zfEC4rETJc+boubBs4sMnNpjYNHP3YziXe/gCiyYjercVaeoLRXWHvXlBtedZFYjlZbyoKZiv8d7DhZgdHvvoZxWA5jt357sRb44fbCV/dPP4Zbn0yvLOSHTwq/5qsqaN6iv7iikqWMV+Z03EXnWZL6BNZFeGGJN6IVOYKfq+zW4UZQLk4l8+n+rVoNJQaKOC0jKvk/+6yE8Zk6ggI65786/jj8gJC1SJssvZLjqTI+i4PDDTOvXMh3pU3bnb0/uHGgG1BX45kqeU/dhd1IQLZVhAUQjiGH+C2+hFGa5C5hYSpHlQ0X0jpw2V/RauwKF0IHbWCX9Bu79EPuX72XtLFu04HSZIercHviaMJfw8AAsb22mZ5gk7xzUsG9Y2kWRMvLMbD","publicKey":"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQm9qQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FZOEFNSUlCaWdLQ0FZRUFzdUhXYUhsZ0I1cVF4ZEJjTlJKSAordHR4SmoxcVY1NTdvMlZaRE1XaXhYRVBkRTBEMVFkT1JIRXNSS1RscmplUXlERU83ZlNQS0ZwZ1A3MU5TTnJCCkFHM2NFSU45aHNQVDhOVmllZmdWem5QTkVMenFkVmdEbFhpb2VpUnV6OERKWFgvblpmU1JWKytwbk9ySTRibG4KS0twelJlNW14OTc1SjhxZ1FvRktKT0NNRlpHdkJMR2MxSzZZaEIzOHJFODZCZzgzbUovWjBEYkVmQjBxZm13cgo2ZDVFUXFsd0E5Y3JZT1YyV1VpWXprSnBLNmJZNzRZNmM1TmpBcEFKeGNiaTFOaDlRVEhUcU44N0ZtMDF0R1ZwCjVNd1pXSWZuYVRUemEvTGZLelR5U0pka0tldEZMVGdkYXpMYlpzUEE2aHBSK0FJRTJhc0tLTi84UUk1N3UzU2cKL2xyMnZKS1IvU2l5eEN1Q20vQWJkYnJMbXk0WjlSdm1jMGdpclA4T0lLQWxBRWZ2TzV5Z2hSKy8vd1RpTFlzUQp1SllDM0V2UE16ZGdKUzdGR2FscnFLZzlPTCsxVzROY05yNWdveVdSUUJ0cktKaWlTZEJVWmVxb0RvSUY5NHpCCndGbzJJT1JFdXFqcU51M3diMWZIM3p1dGdtalFra3IxVjJhd3hmcExLWlROQWdNQkFBRT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg"}

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,26 @@
22

33
All notable changes to this package will be documented in this file.
44

5+
## [1.5.10] - 2026-03-12
6+
7+
### Fixed
8+
9+
- Added missing `Serializable` attribute to `FormatterBase`. ([LOC-1282](https://issuetracker.unity3d.com/product/unity/issues/guid/LOC-1282))
10+
- Added support for BCP 47 resource locale codes on Android 21+. (UUM-132466). ([UUM-132466](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-132466))
11+
- Adjusted the localization tables window so only the search bar shrinks/expands and all other buttons remain fixed. (LOC-1278)
12+
- Changed the Table Key ID Field so it is a selectable label and can now be copied. (LOC-1305)
13+
- Disabled the horizontal scroll in the ReorderableListView component. It was occasionally appearing when unnecessary and should not be required. ([LOC-1287](https://issuetracker.unity3d.com/product/unity/issues/guid/LOC-1287))
14+
- Fix the samples not being included in the package data.
15+
- Fixed alignment of Project Locale identifier field. ([LOC-1277](https://issuetracker.unity3d.com/product/unity/issues/guid/LOC-1277))
16+
- Fixed an issue where nested LocalizedStrings could not have their local variables queried. ([UUM-134944](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-134944))
17+
- Fixed an issue where the ExcludeEntryFromExport metadata would be ignored when exporting to CSV and XLIFF if the first table entry was null. ([UUM-136670](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-136670))
18+
- Fixed Android using the wrong app name locale codes for Indonesian and Hebrew. (LOC-1272)
19+
- Fixed the wrong group being used to resolve assets when a SharedGroup was assigned to the GroupResolver. ([UUM-135659](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-135659))
20+
- Fixed UI Builder picker so it saves the view state.
21+
- Improved fast enter playmode support. (UUM-131023)
22+
- Removed warning when using default localization settings. (LOC-1290)
23+
- When a new String Table is added, the IsSmart flag will now be propagated to its entries if it is already consistently set across all existing tables. ([LOC-1274](https://issuetracker.unity3d.com/product/unity/issues/guid/LOC-1274))
24+
525
## [1.5.9] - 2025-11-13
626

727
### Fixed

Editor/Addressables/GroupResolver.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public void AddLocaleGroup(LocaleIdentifier identifier, AddressableAssetGroup gr
135135
/// <returns>The asset entry for the added asset.</returns>
136136
public virtual AddressableAssetEntry AddToGroup(Object asset, IList<LocaleIdentifier> locales, AddressableAssetSettings aaSettings, bool createUndo)
137137
{
138-
var group = SharedGroup ?? GetGroup(locales, asset, aaSettings, createUndo);
138+
var group = GetGroup(locales, asset, aaSettings, createUndo);
139139
var guid = GetAssetGuid(asset);
140140
var assetEntry = aaSettings.FindAssetEntry(guid);
141141

@@ -238,7 +238,7 @@ static AddressableAssetGroup CreateNewGroup(string name, bool readOnly, Addressa
238238

239239
AddressableAssetEntry GetAssetEntry(Object asset, AddressableAssetSettings aaSettings) => aaSettings.FindAssetEntry(GetAssetGuid(asset));
240240

241-
static string GetAssetGuid(Object asset)
241+
internal virtual string GetAssetGuid(Object asset)
242242
{
243243
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(asset, out var guid, out long _))
244244
return guid;

Editor/Platform/Android/Player.cs

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,14 @@ public static void AddLocalizationToAndroidGradleProject(string projectDirectory
8282
if (appInfo == null)
8383
throw new ArgumentNullException(nameof(appInfo));
8484

85+
var minApi = (int)PlayerSettings.Android.minSdkVersion;
86+
bool useBcp47 = minApi >= 21; // We can use BCP 47 language tags for resource folders on Android 5.0+ (API 21+). https://developer.android.com/guide/topics/resources/localization#bcp47-tags
87+
8588
var project = new GradleProjectSettings();
8689
foreach (var locale in LocalizationEditorSettings.GetLocales())
8790
{
88-
var localeIdentifier = GenerateAndroidLanguageCode(locale.Identifier);
89-
GenerateLocalizedXmlFile("App Name", Path.Combine(Directory.CreateDirectory(Path.Combine(project.GetResFolderPath(projectDirectory), "values-b+" + localeIdentifier)).FullName, k_InfoFile), locale, appInfo);
91+
var localeIdentifier = GenerateAndroidLanguageCode(locale.Identifier, useBcp47);
92+
GenerateLocalizedXmlFile("App Name", Path.Combine(Directory.CreateDirectory(Path.Combine(project.GetResFolderPath(projectDirectory), "values-" + localeIdentifier)).FullName, k_InfoFile), locale, appInfo);
9093

9194
//Generate icons
9295
var folderNames = new List<string>
@@ -127,22 +130,45 @@ public static void AddLocalizationToAndroidGradleProject(string projectDirectory
127130
androidManifest.SaveIfModified();
128131
}
129132

130-
internal static string GenerateAndroidLanguageCode(LocaleIdentifier localeIdentifier)
133+
internal static string GenerateAndroidLanguageCode(LocaleIdentifier localeIdentifier, bool useBcp47)
131134
{
132-
// When we use System Language as Locale Source Chinese (Simplified) code is represented as (zh-hans) and Chinese (Traditional) code is represented as (zh-hant).
133-
// But Android Localization is case-sensitive and ony supports Chinese (Simplified) code as (zh-Hans) and Chinese (Traditional) code as (zh-Hant).
134-
// https://developer.android.com/reference/java/util/Locale.LanguageRange
135-
localeIdentifier = localeIdentifier.Code.Contains("hans") ? localeIdentifier.Code.Replace("hans", "Hans") : localeIdentifier.Code.Contains("hant") ? localeIdentifier.Code.Replace("hant", "Hant") : localeIdentifier;
135+
// Normalize special languages
136136
var code = localeIdentifier.Code;
137137

138-
var IsSpecialLocaleIdentifier = code.Contains("Hans") || code.Contains("Hant") || code.Contains("Latn") || code.Contains("Cyrl") || code.Contains("Arab") || code.Contains("valencia");
138+
// Indonesian and Hebrew legacy codes on Android
139+
if (code.Equals("id", StringComparison.OrdinalIgnoreCase) || code.Equals("id-ID", StringComparison.OrdinalIgnoreCase))
140+
code = "in";
141+
else if (code.Equals("he", StringComparison.OrdinalIgnoreCase) || code.Equals("he-IL", StringComparison.OrdinalIgnoreCase))
142+
code = "iw";
139143

140-
// The language is defined by a two-letter ISO 639-1 language code, optionally followed by a two letter ISO 3166-1-alpha-2 region code (preceded by lowercase r).
141-
// The codes are not case-sensitive; the r prefix is used to distinguish the region portion. You cannot specify a region alone.
142-
// https://developer.android.com/guide/topics/resources/providing-resources
143-
localeIdentifier = code.Contains("-") ? IsSpecialLocaleIdentifier ? code.Replace("-", "+") : code.Replace("-", "-r") : localeIdentifier;
144+
// Normalize Chinese scripts casing
145+
code = code.Replace("hans", "Hans").Replace("hant", "Hant");
144146

145-
return localeIdentifier.Code;
147+
if (useBcp47)
148+
{
149+
// Convert separators to + for BCP 47 resource folders
150+
// e.g., zh-Hans-CN -> b+zh+Hans+CN
151+
return "b+" + code.Replace("-", "+");
152+
}
153+
else
154+
{
155+
// Special handling for es-419
156+
if (code.Equals("es-419", StringComparison.OrdinalIgnoreCase))
157+
return "es-rMX";
158+
159+
// Detect script/variant presence
160+
bool hasSpecialSubtag = code.Contains("Hans") || code.Contains("Hant") ||
161+
code.Contains("Latn") || code.Contains("Cyrl") ||
162+
code.Contains("Arab") || code.Contains("valencia");
163+
164+
// Legacy -r folders: lang[-rREGION]
165+
// Only insert -r if there is a hyphen and no script/variant that would be invalid pre-21
166+
// e.g., en-GB -> en-rGB ; es-MX -> es-rMX
167+
if (code.Contains("-") && !hasSpecialSubtag)
168+
return code.Replace("-", "-r");
169+
170+
return code;
171+
}
146172
}
147173

148174
static void GenerateIconDirectory(List<string> folderNames, string path, Locale locale)

Editor/Plugins/CSV/CSV.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public static void Export(TextWriter writer, StringTableCollection collection, I
8282
reporter?.ReportProgress("Writing Contents", 0.1f);
8383
foreach (var row in collection.GetRowEnumeratorUnsorted())
8484
{
85-
if (row.TableEntries[0] != null && row.TableEntries[0].SharedEntry.Metadata.HasMetadata<ExcludeEntryFromExport>())
85+
if (row.KeyEntry.Metadata.HasMetadata<ExcludeEntryFromExport>())
8686
continue;
8787

8888
csvWriter.NextRecord();

Editor/Plugins/Xliff/Xliff.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public static void AddTableToDocument(IXliffDocument document, StringTable sourc
191191

192192
foreach (var row in StringTableCollection.GetRowEnumerator(source, target))
193193
{
194-
if (row.TableEntries[0] != null && row.TableEntries[0].SharedEntry.Metadata.HasMetadata<ExcludeEntryFromExport>())
194+
if (row.KeyEntry.Metadata.HasMetadata<ExcludeEntryFromExport>())
195195
continue;
196196

197197
var unit = group.AddNewTranslationUnit();

Editor/Settings/StringTableCollection.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using UnityEngine.Localization;
77
using UnityEngine.Localization.Metadata;
88
using UnityEngine.Localization.Tables;
9+
using UnityEngine.Pool;
910
using static UnityEngine.Localization.Tables.SharedTableData;
1011

1112
namespace UnityEditor.Localization
@@ -105,6 +106,52 @@ internal void MergeUpdatedEntries(HashSet<long> entriesToKeep, List<SharedTableE
105106
SharedData.Entries = sortedEntries;
106107
}
107108

109+
/// <inheritdoc/>
110+
public override LocalizationTable AddNewTable(LocaleIdentifier localeIdentifier, string path)
111+
{
112+
// Record the Smart string entries so we can sync the new table to match.
113+
using (HashSetPool<long>.Get(out var smartStringEntries))
114+
{
115+
var tables = StringTables;
116+
foreach(var entry in SharedData.Entries)
117+
{
118+
bool isSmart = false;
119+
foreach (var table in tables)
120+
{
121+
if (table.GetEntry(entry.Id)?.IsSmart != true)
122+
{
123+
isSmart = false;
124+
break;
125+
}
126+
isSmart = true;
127+
}
128+
129+
// If all the entries are marked as smart then we want to do the same to the new table.
130+
if (isSmart)
131+
smartStringEntries.Add(entry.Id);
132+
}
133+
134+
var newTable = base.AddNewTable(localeIdentifier, path);
135+
136+
// Now sync the new table's smart string entries.
137+
var stringTable = (StringTable)newTable;
138+
foreach (var entryId in smartStringEntries)
139+
{
140+
var entry = stringTable.AddEntry(entryId, string.Empty);
141+
entry.IsSmart = true;
142+
}
143+
144+
if (smartStringEntries.Count > 0)
145+
{
146+
EditorUtility.SetDirty(stringTable);
147+
SaveChangesToDisk();
148+
LocalizationEditorSettings.EditorEvents.RaiseCollectionModified(this, this);
149+
}
150+
151+
return newTable;
152+
}
153+
}
154+
108155
/// <summary>
109156
/// Returns an enumerator that can be used to step through each key and its localized values, such as in a foreach loop.
110157
/// Internally <see cref="SharedTableData"/> and <see cref="StringTable"/>'s are separate assets with their own internal list of values.

Editor/UI/Localized Reference/TableReferenceField.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,12 @@ void RefreshTableDetails()
276276
void OnSelectEntry()
277277
{
278278
var provider = CreateSearchProvider();
279+
280+
#if UNITY_2022_3_OR_NEWER
281+
var context = UnityEditor.Search.SearchService.CreateContext(new[] { provider }, string.Empty, SearchFlags.UseSessionSettings);
282+
#else
279283
var context = UnityEditor.Search.SearchService.CreateContext(provider);
284+
#endif
280285

281286
var picker = new LocalizedReferencePicker<TCollection>(context, "table entry", m_TableProperty, m_EntryProperty);
282287
picker.Show();

Editor/UI/Settings/Locale/LocaleIdentifierPropertyDrawer.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public override VisualElement CreatePropertyGUI(SerializedProperty property)
2323
foldout.BindProperty(property);
2424

2525
var localeField = new ObjectField { objectType = typeof(Locale), value = LocalizationEditorSettings.GetLocale(code.stringValue) };
26+
localeField.Q<Label>().RemoveFromClassList("unity-text-element"); // Prevent the margin being removed
2627
localeField.AddToClassList("unity-base-field__input");
2728
localeField.RegisterCallback<MouseDownEvent>(evt => evt.StopPropagation());
2829
localeField.RegisterCallback<MouseUpEvent>(evt => evt.StopPropagation());
@@ -35,6 +36,8 @@ public override VisualElement CreatePropertyGUI(SerializedProperty property)
3536
foldout.hierarchy[0].Add(localeField);
3637
foldout.hierarchy[0].hierarchy[0].RemoveFromClassList("unity-base-field__input");
3738
foldout.hierarchy[0].hierarchy[0].AddToClassList("unity-base-field__label");
39+
foldout.hierarchy[0].hierarchy[0].style.paddingLeft = 0;
40+
localeField.style.marginRight = 0;
3841

3942
var codeField = new TextField { label = "Code" };
4043
codeField.RegisterValueChangedCallback(evt =>

0 commit comments

Comments
 (0)