Hey,
Itâs certainly on our roadmap but will be some time before we have an official integration.
We are talking with the UI toolkit team at the moment.
If you need something in the short term the you should look at adding your own integration, I canât really give any firm dates for an integration yet.
In case sb needs to integrate these two packages I attach my working example you can start with. It handles runtime language changes too (this resets hierarchy tho).
UIDocumentLocalization.cs
This class assumes that you designate StringTable keys in label fields (as seen in Label, Button, etc) and start them all with â#â char (so other labels will be left be)
Example: Imgur: The magic of the Internet
// void* src = https://gist.github.com/andrew-raphael-lukasik/72a4d3d14dd547a1d61ae9dc4c4513da
using UnityEngine;
using UnityEngine.UIElements;
using UnityEngine.Localization;
using UnityEngine.Localization.Tables;
using UnityEngine.ResourceManagement.AsyncOperations;
// NOTE: this class assumes that you designate StringTable keys in label fields (as seen in Label, Button, etc)
// and start them all with '#' char (so other labels will be left be)
// example: https://i.imgur.com/H5RUIej.gif
[DisallowMultipleComponent]
[RequireComponent( typeof(UIDocument) )]
public class UIDocumentLocalization : MonoBehaviour
{
[SerializeField] LocalizedStringTable _table = null;
UIDocument _document;
/// <summary> Executed after hierarchy is cloned fresh and translated. </summary>
public event System.Action onCompleted = ()=>{};
void OnEnable ()
{
if( _document==null )
_document = gameObject.GetComponentInParent<UIDocument>( includeInactive:true );
_table.TableChanged += OnTableChanged;
}
void OnDisable ()
{
_table.TableChanged -= OnTableChanged;
}
void OnTableChanged ( StringTable table )
{
var root = _document.rootVisualElement;
root.Clear();
_document.visualTreeAsset.CloneTree( root );
var op = _table.GetTable();
op.Completed -= OnTableLoaded;
op.Completed += OnTableLoaded;
}
void OnTableLoaded ( AsyncOperationHandle<StringTable> op )
{
StringTable table = op.Result;
var root = _document.rootVisualElement;
LocalizeChildrenRecursively( root , table );
onCompleted();
root.MarkDirtyRepaint();
}
void Localize ( VisualElement next , StringTable table )
{
if( typeof(TextElement).IsInstanceOfType(next) )
{
TextElement textElement = (TextElement) next;
string key = textElement.text;
if( !string.IsNullOrEmpty(key) && key[0]=='#' )
{
key = key.TrimStart('#');
StringTableEntry entry = table[ key ];
if( entry!=null )
textElement.text = entry.LocalizedValue;
else
Debug.LogWarning($"No {table.LocaleIdentifier.Code} translation for key: '{key}'");
}
}
}
void LocalizeChildrenRecursively ( VisualElement element , StringTable table )
{
VisualElement.Hierarchy elementHierarchy = element.hierarchy;
int numChildren = elementHierarchy.childCount;
for( int i=0 ; i<numChildren ; i++ )
{
VisualElement child = elementHierarchy.ElementAt( i );
Localize( child , table );
}
for( int i=0 ; i<numChildren ; i++ )
{
VisualElement child = elementHierarchy.ElementAt( i );
VisualElement.Hierarchy childHierarchy = child.hierarchy;
int numGrandChildren = childHierarchy.childCount;
if( numGrandChildren!=0 )
LocalizeChildrenRecursively( child , table );
}
}
}
Oh, youâre right, didnât noticed that before! I will investigate it sometime soon but Iâm surprised this handler isnât being unsubscribed, like, at all.
I hope itâs my silly mistake somewhere and not custom event accessor shenanigans.
Not sure why but events stopped pilling up today and I canât reproduce that behavior anymore. Maybe it was Unity version related? (on 2020.3.0f1 now)
Other than that I can see an exception when translation event is raised due to m_ChangeHandler being null in com.unity.localization@0.10.0-preview. To fix it just add âif( m_ChangeHandler!=null )â at line 139 in LocalizedTable.cs
stacktrace
NullReferenceException: Object reference not set to an instance of an object
UnityEngine.Localization.LocalizedTable`2[TTable,TEntry].AutomaticLoadingCompleted (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[TObject] loadOperation) (at Packages/com.unity.localization@0.10.0-preview/Runtime/Localized Reference/LocalizedTable.cs:140)
DelegateList`1[T].Invoke (T res) (at Library/PackageCache/com.unity.addressables@1.16.13/Runtime/ResourceManager/Util/DelegateList.cs:69)
UnityEngine.Debug:LogException(Exception)
DelegateList`1:Invoke(AsyncOperationHandle`1) (at Library/PackageCache/com.unity.addressables@1.16.13/Runtime/ResourceManager/Util/DelegateList.cs:73)
UnityEngine.Localization.LoadTableOperation`2:TableLoaded(AsyncOperationHandle`1)
DelegateList`1:Invoke(AsyncOperationHandle`1) (at Library/PackageCache/com.unity.addressables@1.16.13/Runtime/ResourceManager/Util/DelegateList.cs:69)
UnityEngine.ResourceManagement.Util.DelayedActionManager:LateUpdate() (at Library/PackageCache/com.unity.addressables@1.16.13/Runtime/ResourceManager/Util/DelayedActionManager.cs:159)