Double-nested Localiztion

Hi,

I have a question regarding nested strings in Localization.

If I have a smart string, is it possible to do as following as following:
“key_timer” with a smartstring english-"Time left: {countdown}
and then set countdown to one of following:
“key_hh_mm_ss” with value “{time_h}{time_unit_h} {time_m}{time_unit_m} {time_s}{time_unit_s}”
“key_mm_ss” with value “{time_m}{time_unit_m} {time_s}{time_unit_s}”
“key_ss” with value “{time_s}{time_unit_s}”

so that as the timer progress I can update “countdown” from “key_hh_mm_ss” to “key_mm_ss” and finally “key_ss”

Instead of a solution where I would need to have 3 different types of:
“key_timer_hh_mm_ss” with value “Time left: {time_h}{time_unit_h} {time_m}{time_unit_m} {time_s}{time_unit_s}”
“key_timer_mm_ss” with value “Time left: {time_m}{time_unit_m} {time_s}{time_unit_s}”
“key_timer_ss” with value “Time left: {time_s}{time_unit_s}”

I have a lot of timers in my game and would like to not make 3 different for every text.

How would one solve this?

Thanks in advance!

I think for this you would be better creating a custom source or formatter.

The source could return a the string
https://docs.unity3d.com/Packages/com.unity.localization@1.4/manual/Smart/Creating-a-Custom-Source.html

Or you could return a custom data type to represent the timers and then have a custom formatter that converts it into a string later on
https://docs.unity3d.com/Packages/com.unity.localization@1.4/manual/Smart/Creating-a-Custom-Formatter.html

Thanks!

The first solution looked easier and interesting. However I couldn’t make it work. It says one should add it to sources but the link https://docs.unity3d.com/Packages/com.unity.localization@1.4/manual/Smart/LocalizationSettings.md#sources
doesn’t exist.

I figured that it was solved as followed:

I have set the key/value as following

What am I missing?

Do you get any errors?

My bad. There is an error in the text in the documentation:
https://docs.unity3d.com/Packages/c…4/manual/Smart/Creating-a-Custom-Source.html
an parentheses is set as a curly bracket.

Thanks!

I can’t find in the documentation how one updates the values outside of Project Setting.

Am I correct in that it doesn’t seem to be possible to put localized values inside the options as following:
{random:choose(1|2|3) : {example_1} | {example_2}{example3} | {example_4}} ?

Hi,
Sorry I missed your message. I’ll get the docs page fixed.
You can put localized values in but they need to be configured through a LocalizedString.

E.G

var localizedString = new LocalizedString("Some Table", "Some Value");// {random:choose(1|2|3) : {example_1} | {example_2}{example3} | {example_4}}

localizedString.Add("example_1", new LocalizedString("Some Table, "example_1_entry"));

Debug.Log(localizedString.GetLocalizedString());

Hi,
No worries, thanks for all your help! :slight_smile:

2 questions:

  1. I couldn’t find in the documentation how to change the “random” variable other than manually going into the Project Setting. How does one change it through script?

  2. I couldn’t get the example to work.
    In my case I used it like this (with some table changed to the table I was currently working on of course)

var localizedString = new LocalizedString("Some Table", "{random:choose(1|2|3) : {example_1} | {example_2}{example3} | {example_4}}");
localizedString.Add("example_1", new LocalizedString("Some Table, "test string"));
Debug.Log(localizedString.GetLocalizedString());

I only got a missing entry comment in the console.

You need an entry in the string table with the text "{random:choose(1|2|3) : {example_1} | {example_2}{example3} | {example_4}}");", you can’t feed it directly into the LocalizedString.
Do you need to change this entry at runtime? That may be difficult if you are trying to dynamically change a string entry as it could be different for each language.

If you need to get to the entry you can use a LocalizedStringTable or call LocalizationSettings.StringDatabase.GetTable.

You can also update a table after build, https://docs.unity3d.com/Packages/com.unity.localization@1.4/manual/Scripting.html#applying-changes-to-a-table-after-the-game-is-built

Sorry. No, I think I might have missunderstood what you meant above when you wrote:

var localizedString = new LocalizedString("Some Table", "Some Value");// {random:choose(1|2|3) : {example_1} | {example_2}{example3} | {example_4}}
localizedString.Add("example_1", new LocalizedString("Some Table, "example_1_entry"));
Debug.Log(localizedString.GetLocalizedString());

But one think that I really can’t wrap my head around is how I can change/assign 1, 2 or 3 in the example above, in “random:choose(1|2|3)”. If I want it to not be random but assign alternativ 1, 2 or 3 at runtime. Only solution I found was editing it during edit mode.

Thanks in advance!

Hmm, what’s your use case here? Im not sure why you would want to change the arguments at runtime, it would make it hard to translate if you are changing the string arguments.
You can get the whole string and edit that, there’s no simple way to get just 1,2,3 and change them though. You would first need to parse the string to extract the values and then re-insert the new ones.
What is the string you are trying to create? You may find it simpler to just extract the value you need from the table instead of letting the smart string do it.

What I’m trying to do is understand how I can manipulate the selection of alternatives at runtime.

For example, I just tried to use the following code. It “works”. But it always, always selects “1”. Even though I try to assign it to “2” or “3”.

What I really want to do is try to change it at runtime depending on circumstances, so that by “picking” 1, 2 or 3 I may change part of the text.

public class SelectorScript : ISource
{
    public int pick = 2;

    public string selector = "random";

    public bool TryEvaluateSelector(ISelectorInfo selectorInfo)
    {
        if (selectorInfo.SelectorText != selector)
            return false;
        selectorInfo.Result = pick;
        return true;
    }
}

Thats strange, if you are using "{random:choose(1|2|3) : One|Two|Three|Other");" and the ISource is passing in 2 then you should be getting “Two”. Can you debug and make sure its returning true and passing in 2?
Did you also assign the source to the Localization Settings?

Are you able to share a sample project with the issues you are having?

Absolutly but how does one share a project? I’m guessing I shouldn’t attach the project here as a file?

I debuged but couldn’t understand how it works as it didn’t change the value in Project Setting. It only works when I enter Project Settings in Editor Mode and manually change it to a value.

In my game I really don’t want it to be randomly chosen but changed at runtime depending on in-game scenarios.

Thanks again for all your help!