Can you share the code? I dont see anywhere in the code above where you use the string. Do you need to add another GUILayout.Label in your OnGUI for the string?
In the second screenshot you can see the Inpector of the TextMeshProText element where I’m setting the text.
The Localize String component sets the text “Hits{Hits}x” in the TextMeshProText element.
The following code does this: In the file HitsLocalization.cs I retrieve the value of PlayerPrefs.GetInt(“Hits”) and set it to the public variable int Hits:
// File HitsLocalization.cs
public string Hits;
void Start()
{
// PlayerPrefs contains the value 100
Hits = PlayerPrefs.GetInt("Hits");
}
Then I drag the file HitsLocalization.cs into the Element 0 in the Format Arguments of the component Localize String (screenshot 2).
The problem is the following:
The text shown when loading the game is: “Hits 0x”, but if I change the language of the game through the dropdown in the top right of the Game view, the text updates correctly to: “Hits 100x”.
That means the Start() executed after the component Localize String and the value of Hits didn’t get updated.
I tried Awake() and it didn’t worked too.
So I think I can see what you are doing.
You have a Localize String attached to the text which is doing the update.
The Localize String is using the Arguments provided by your script.
So if I’m correct then you don’t need the LocalizedString component in your class, there is already one in the Localize String component. Changes made to LocalizedString will not be made to other LocalizedStrings in the world, this is by design. They operate independent of each other, so you could provide different arguments to the same localized string.
You just need to call RefreshString on the LocalizedString that is part of the component attached to the text.
public class Hits : MonoBehaviour
{
public int Hits;
public LocalizeStringEvent localizeString; // Hold a reference to the LocalizeStringBehaviour component. Assign this in the inspector.
void OnEnable()
{
Hits = PlayerPrefs.GetInt("Hits");
localizeString.StringReference.RefreshString();
}
void Update()
{
// If the value changes then just call RefreshString again
//localizeString.StringReference.RefreshString();
}
}
Hi, I tried the code you suggested and Visual Studio throws an error about the class LocalizeStringEvent doesn’t exists, I checked and using UnityEngine.Localization; is in the file.
Nevermind, I found the error, it was LocalizeStringBehaviour instead LocalizeStringEvent class.
Thank you so much for the help, the localization tool is amazing, you are doing a great work
Having one example about using LocalizeStringBehaviour in the docs should be really useful too.
I’m trying to use this method, and it does work in editor.
However, for some reason, smart values are always blank and do not correctly get updated when I am building for android.
I’m not seeing any exceptions. putting in break points, i can see my getters getting called, but the final string is stripped of any smart format objects.
Seems that for some reason, the formatter is null. Here is the exception coming up on adb logcat:
2020-05-26 15:30:15.345 19268-19302/co.arctop.gaming E/Unity: FormattingException: Error parsing format string: Value cannot be null.
Parameter name: source at 266
You will be presented with a series of exercises (like: 100 +21 = )
Write the correct answer and press the ‘Done’ button as quickly as possible.
The calculations should be done only in your head, and without using a paper or calculator.
You will have {SessionTime} {SessionMeasureUnits} to complete this task.
Have fun!
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------^
at UnityEngine.Localization.SmartFormat.SmartFormatter.FormatError (UnityEngine.Localization.SmartFormat.Core.Parsing.FormatItem errorItem, System.Exception innerException, System.Int32 startIndex, UnityEngine.Localization.SmartFormat.Core.Formatting.FormattingInfo formattingInfo) [0x00054] in E:\Dev\Gaming_Library_Native
Added an image of the stack trace as well.
Why would the formatter be null? the values of my properties are set, and it does work in editor. I have made sure to build the addressables. It is just the smart object that fails.
Do you know which formatter is going null? There was some bugs with the SerializeReference feature that caused this to happen. What version of Unity are you using? Can you try the latest?
Some people have mentioned that the List formatter is going null for them, ty removing if if you are not using it.
Using latest. Not sure which one it was. I will try and play around with the settings, but it is a holiday now here so not available to check until next Sunday. Will circle back with more info when I can.
in SmartFormatter.cs , InvokeFormatterExtensions()
the formatter name property accessed in line 387: (see screenshot_1)
var formatterName = formattingInfo.Placeholder.FormatterName;
Is an empty string. The placeholder is valid, but no format or name is present here.
The stacktrace here is GetLocalizedString->FormatWithCache->Format->Format->EvaluateFormatters->InvokeFormatterExtension (see stacktrace.png).
Upon further playing around, it appears that removing the ListFormatter from the settings does result in correct working solution in build as well.
Hello,
I’m jumping into this thread as I have a related issue. How do you manage to put a variable of a script as an argument for a smart string like in your screenshot where it’s written “Hits(HitsLocalization)” in Format arguments ?
I’ve carefully followed the manual and this thread, but I always end up with the error : “Could not evaluate the selector”.
I’m also a bit lost with smart format… Here is what I have
I’ve added that script as a componenent in my label gameobject. It has finally worked with integers for another field, but here with the boolean, impossible to make it work.
using TMPro;
using UnityEngine;
using UnityEngine.Localization;
public class LocalizedFocus : MonoBehaviour
{
public LocalizedString myString;
string localizedText;
public bool focusMode = true;
public TMP_Text focusLabel;
/// <summary>
/// Register a ChangeHandler. This will be called whenever we need to update our string.
/// </summary>
void OnEnable()
{
myString.Arguments = new[] { this };
myString.RegisterChangeHandler(UpdateString);
}
private void OnDisable()
{
myString.ClearChangeHandler();
}
void UpdateString(string s)
{
localizedText = s;
}
void OnGUI()
{
// This will either call UpdateString immediately (if the table is loaded) or when the table is available.
myString.RefreshString();
focusLabel.text = localizedText;
// GUILayout.Label(localizedText);
}
}
Hi,
I can see how Smart Format can be a bit confusing. We do want to make it easier in the future.
I recreated your example and the problem you have is that you are using the {0} syntax but passing in an instance of LocalizedFocus which is not a bool. If you want to use the focusMode variable then you need to either pass in the variable as an argument or change the Smart Format string to use it.
So to pass the argument you would do:
myString.Arguments = new[] { (object)focusMode };
When you change the value of focusMode you will need to change the arguments as this value will be held by value, not reference.
Alternatively use this as your Smart String: “{focusMode:focus Mode|Cool Mode}”
Thank you. I’ve tried both alternatives, they work well in the editor, but on ios devices, I get the same issue “Could not evaluate the selector”. Do you have an idea from where it may come ?