Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Is it possible to use a localized string inside a a Smart String?

Discussion in 'Localization Tools' started by GPaduanoImmerxive, Sep 13, 2022.

  1. GPaduanoImmerxive

    GPaduanoImmerxive

    Joined:
    Jan 19, 2022
    Posts:
    14
    Hi :) I'm trying to understand if is possible to do what is said in the title.

    For example, supposing to have a smart string like this:

    {vehicleType} is {vehicleStatus}

    where carname and velocity can assume different values and are localized.

    Carname
    values are {car, motorbyke, bicycle}.
    Velocity values are {free, reserved}.

    For example I want strings like:
    "Car is free",
    "Bicycle is reserved},
    etc...​

    Given this setup, when I go to change the language, these strings must be localized correctly.

    How can I manage this kind of situations?

    Thank you so much :)
     
    Last edited: Sep 13, 2022
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,876
    Yes, you can use nesting of localized strings but you should be careful about it.
    The structure may need to change when dealing with languages such as Spanish where the gender of the object can change the other words. For example, see here https://docs.unity3d.com/Packages/c...sistent-Variables-Source.html#handling-gender
    The gender example is available through the Samples which can be found in the package manager.
    You should be able to do something similiar. If you dont have a lot of objects and states then it may be worth just having each sentence as a separate table entry, this will be much easier for a translator to work with.
     
  3. GPaduanoImmerxive

    GPaduanoImmerxive

    Joined:
    Jan 19, 2022
    Posts:
    14
    Hi, thank you for the answer :). Since I'm doing it via script, as I was doing here, can you help me with the setup?

    Actually I add the LocalizeStringEvent to the interested GameObject as follows:
    Code (CSharp):
    1. // Add LocalizeStringEvent component
    2. targetGameObject.AddComponent<LocalizeStringEvent>();
    3.  
    4. // Assign text to update
    5. TextMeshProUGUI textToUpdate = data.text;
    6.  
    7. // Setup LocalizeString.
    8. LocalizedString localizeString = new LocalizedString("table_name", "entry_name");
    9.  
    10. // Setup smart fields
    11. localizeString.Add("smartFieldName1", new StringVariable { Value = valueToAssign });
    12. localizeString.Add("smartFieldName2", new StringVariable { Value = valueToAssign });
    13.  
    14. // Assign localized string and setup update
    15. targetGameObject.GetComponent<LocalizeStringEvent>().StringReference = localizeString;
    16. targetGameObject.GetComponent<LocalizeStringEvent>().OnUpdateString.AddListener(x => textToUpdate.text = x);
    17. targetGameObject.GetComponent<LocalizeStringEvent>().StringReference.RefreshString();
    But I can't figure out how to add nested localization setup :(.

    Thank you :)
     
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,876
    A nested localized string is done by adding it as a persistent variable to a LocalizedString.
    https://docs.unity3d.com/Packages/c...ent-Variables-Source.html#nested-translations

    It can be done through script like this: https://docs.unity3d.com/Packages/c...gine_Localization_Tables_TableEntryReference_

    Code (csharp):
    1. public LocalizedString withNestedTranslation = new LocalizedString("My String Table", "My Game Text")
    2. {
    3.    { "some-text", new StringVariable { Value = "Hello World" } },
    4.    { "nested", new LocalizedString("My String Table", "My Nested Text")
    5.      {
    6.          { "score", new IntVariable { Value = 100 } },
    7.      }}
    8. };
    You can also call Add on an existing LocalizedString.

    Code (csharp):
    1. myString.Add("nested-string", new LocalizedString("My String Table", "My Nested Text");
     
    GPaduanoImmerxive likes this.
  5. GPaduanoImmerxive

    GPaduanoImmerxive

    Joined:
    Jan 19, 2022
    Posts:
    14
    So, supposing I want to continue my above implementation and supposing I have the following table where ItemText is the SmartString to setup:

    upload_2022-9-13_16-38-39.png

    As you said, I can add persistent serialized arguments by using Add. I should to it in lines 11 and 12. What I don't understand is the values to assign. If there are multiple values (item = {pen, backpack} - color = {red, blue, etc...}, how can I add the right value?
    Code (CSharp):
    1. // Add LocalizeStringEvent component
    2. targetGameObject.AddComponent<LocalizeStringEvent>();
    3.  
    4. // Assign text to update
    5. TextMeshProUGUI textToUpdate = data.text;
    6.  
    7. // Setup LocalizeString.
    8. LocalizedString localizeString = new LocalizedString("table_name", "entry_name");
    9.  
    10. // Setup smart fields
    11. localizeString.Add("item", new StringVariable { Value = ?? });
    12. localizeString.Add("color", new StringVariable { Value = ?? });
    13.  
    14. // Assign localized string and setup update
    15. targetGameObject.GetComponent<LocalizeStringEvent>().StringReference = localizeString;
    16. targetGameObject.GetComponent<LocalizeStringEvent>().OnUpdateString.AddListener(x => textToUpdate.text = x);
    17. targetGameObject.GetComponent<LocalizeStringEvent>().StringReference.RefreshString();
     
  6. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,876
    If you look at the sample scene for this example you will see how we do it.

    You can add the nested strings and leave them empty.
    Code (csharp):
    1. localizeString.Add("item", new LocalizedString());
    2. localizeString.Add("color", new LocalizedString());
    Then change their values at a later point when you need them.
    Code (csharp):
    1. public void SetItem(string itemName)
    2. {
    3.     var item = localizeString["item"] as LocalizedString;
    4.     item.SetReference("My Table", itemName);
    5. }
    In our example when a button is pressed we update the nested value upload_2022-9-13_16-47-37.png

    Code (csharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4. using UnityEngine.Localization;
    5. using UnityEngine.Localization.Components;
    6.  
    7. public class SetLocalVariable : MonoBehaviour
    8. {
    9.     public LocalizeStringEvent localizedString;
    10.  
    11.     public void SetNestedStringEntry(string variableAndEntry)
    12.     {
    13.         var args = variableAndEntry.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
    14.         if (args.Length != 2)
    15.             return;
    16.  
    17.         if (localizedString.StringReference[args[0]] is LocalizedString nested)
    18.         {
    19.             nested.TableEntryReference = args[1];
    20.         }
    21.     }
    22. }
    23.  
     
    GPaduanoImmerxive likes this.
  7. GPaduanoImmerxive

    GPaduanoImmerxive

    Joined:
    Jan 19, 2022
    Posts:
    14
    Ahhhh, ok. I got it! Thank you so much! :):):)
     
    karl_jones likes this.