Hello.
For those who want to integrate Unity Localization with the UI Toolkit, here is one of the possible solutions.
In the last few days I had some problems translating/localizing my game. Then I found a post ( UI Toolkit support? )[ @andrew-lukasik ], with a code to translate the interface (thanks a lot)
His code bugged my buttons, they no longer received click events.
So I made mine based on his, credits to him
To use, add the script to the component that has the UIDocument, select the table and run (be happy).
As explained by user andrew-lukasik, the keys must start with “#”.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Tables;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UIElements;
[DisallowMultipleComponent]
[RequireComponent(typeof(UIDocument))]
public class UIToolkitLocalization : MonoBehaviour
{
[SerializeField] LocalizedStringTable table;
List<LocalizeObj> elementList = new List<LocalizeObj>();
void Awake()
{
var document = gameObject.GetComponentInParent<UIDocument>(includeInactive: true);
RegisterElements(document.rootVisualElement);//Register all text elements
}
void OnEnable() => table.TableChanged += OnTableChanged;
void OnDisable() => table.TableChanged -= OnTableChanged;
void OnTableChanged(StringTable stringTable)//if you change the language, the values are updated
{
var tb = table.GetTableAsync();
tb.Completed -= OnTableLoaded;
tb.Completed += OnTableLoaded;
}
void OnTableLoaded(AsyncOperationHandle<StringTable> table)//Updates values if language changes
{
Localize(table.Result);
}
void RegisterElements(VisualElement element)//Register all elements ( recursive )
{
//if have text
if (typeof(TextElement).IsInstanceOfType(element))
{
var textElement = (TextElement)element;
var key = textElement.text;
if (!string.IsNullOrEmpty(key) && key[0] == '#')
{
key = key.TrimStart('#');
elementList.Add(new LocalizeObj
{
Element = textElement,
Key = key
});
}
}
//if have child
var hierarchy = element.hierarchy;
var childs = hierarchy.childCount;
for (int i = 0; i < childs; i++)
{
RegisterElements(hierarchy.ElementAt(i));
}
}
void Localize(StringTable stringTable)//Change text values
{
foreach (var item in elementList)
{
var entry = stringTable[item.Key];
if (entry != null)
item.Element.text = entry.LocalizedValue;
else
Debug.LogWarning($"No {stringTable.LocaleIdentifier.Code} translation for key: '{item.Key}'");
}
}
class LocalizeObj//Used for translation
{
public string Key;
public TextElement Element;
}
}