Search Unity

Localization files

Discussion in 'UI Toolkit' started by tea42, Dec 17, 2018.

  1. tea42

    tea42

    Joined:
    Jul 10, 2013
    Posts:
    18
    Hi,

    I've just stumbled across the new uielements system - it looks like a really nice addition to the editor, thank you! I've been playing around with it a bit today and was wondering if there are any best practices in place for storing strings used in the uxml files? It would be great to be able to store them in a key-value file and pass the key to the uxml to keep things neat - is this (or something similar) possible?

    Thanks in advance,
     
  2. tea42

    tea42

    Joined:
    Jul 10, 2013
    Posts:
    18
    For reference; at the moment I'm adding a unique name to all of the labels I'm using and then referencing them in the OnEnable method in the editor script (example below)...it feels pretty clunky after several lines, so I get the feeling I'm going down a bad path...

    uxml = new UIElementTestUXML();
    uxml.Q<Label>("settings-not-found").text = string.Format(UIElementTestStrings.SaveSettingsNotFound, UIElementTestStrings.SaveSettingsPath);
     
  3. Devi-User

    Devi-User

    Joined:
    Apr 30, 2016
    Posts:
    61
    Try this
    <ui:Label name="my-label" text="My Text"/>
     
  4. tea42

    tea42

    Joined:
    Jul 10, 2013
    Posts:
    18
    Thanks for your response. Rather than inlining the text, my question was whether there was a process for externalising it.

    i.e, in the uxml
    <ui:Label name="my-label" key="component.name.main.header"/>

    then have a key-value pair text localisation file that you would load alongside the uxml with the following:
    component.name.main.header=Component Header Text

    in that way, if building an editor tool for use in multiple countries, it's possible to specify the language and just switch out the file with the localised text in it. It's then also easier to reuse common strings and keep a cleaner workflow.
     
    Devi-User likes this.
  5. tea42

    tea42

    Joined:
    Jul 10, 2013
    Posts:
    18
    ok, so I revisited this and this is currently the solution I have:

    UXML file:
    Code (CSharp):
    1. <UXML xmlns:ui="UnityEngine.Experimental.UIElements" xmlns:cec="CustomEditor.Components" xmlns:uie="UnityEditor.Experimental.UIElements">
    2.     <ui:VisualElement class="root-container">
    3.         <cec:CCLabel key="custom.editor.header" class="h1"/>
    4. </ui:VisualElement>
    5. </UXML>
    Custom component:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Experimental.UIElements;
    3.  
    4. namespace CustomEditor.Components
    5. {
    6.     public class CCLabel : Label
    7.     {
    8.         public new class Factory : UxmlFactory<CCLabel, LabelTraits>
    9.         {
    10.         }
    11.  
    12.         public class LabelTraits : UxmlTraits
    13.         {
    14.             private UxmlStringAttributeDescription key;
    15.  
    16.             public LabelTraits()
    17.             {
    18.                 var attributeDescription2 = new UxmlStringAttributeDescription {name = "key"};
    19.                 key = attributeDescription2;
    20.             }
    21.  
    22.             public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
    23.             {
    24.                 base.Init(ve, bag, cc);
    25.                 Debug.Log("getting label " + key.GetValueFromBag(bag, cc));
    26.                 ((CCLabel) ve).text = Localization.Keys[key.GetValueFromBag(bag, cc)];
    27.             }
    28.         }
    29.     }
    30. }
    Then I have a (quick and dirty) singleton called Localization containing key value pairs for the strings.

    NB. I'm using 2018.3
     
    Last edited: Dec 24, 2018
  6. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    We don't have any specialized localization support built into UIElements at this time. Your solution is not bad. I would have just used the name property directly instead of deriving a new Label element. You can then assign all "localization ready" Labels a special class and only include those labels in your localization initialization step.