How to justify with TMP and LocalisationSystem

Hi Everyone!
I’m Luca and I’m new here.
I am trying to develop an RPG in my spare time and without too many pretensions.

A few months ago I implemented the “LocalizationSystem”. Everything worked correctly.

A month ago I created a combat log, but every time I exceeded a limited number of characters Unity signaled me that I exceeded 65,000 vertices and the Log disappeared.

I solved by replacing the text box in my UI with a TextMeshPro.

When i play in english everything works correctly, but when I play in Italian the localized words are all shifted to the left as you can see in the attached image.

Just to give some more info, these are the variables in my BattleLogManager:

public class BattleLogManager : MonoBehaviour
{
    public static BattleLogManager instance;
 
    public TMP_Text battleLogText;
    public Image battleLogImage;

    public ScrollRect combatLogScrollRect;

    public int maxLogLenght;
    public List<string> combatLog;
...

this is the script to add a string to the Log:

public void addLog (string LogToAdd)
    {
        combatLog.Add(LogToAdd);

        if (combatLog.Count >= maxLogLenght)
        {
            combatLog.RemoveAt(0);
        }

        string combatLogText = "";

        for (int i = 0; i < combatLog.Count; i++)
        {
            if (combatLog[i] != "")
            {
                combatLogText = combatLogText + combatLog[i] + "\n";
            }
        }

        battleLogText.text = combatLogText;     

        combatLogScrollRect.velocity = new Vector2(0f, 1000f);
        newLogTimer = 5f;
        FadeIn();
     
    }

and these are examples of how I call that script to add a string:

BattleLogManager.instance.addLog(activeBattlers[currentTurn].charName + " " + LocalisationSystem.GetLocalisedValue("attack") + " (" + LocalisationSystem.GetLocalisedValue(theMove.moveName) + ") " + activeBattlers[selectedTarget].charName);

or:

BattleLogManager.instance.addLog(activeBattlers[currentTurn].charName + " " + LocalisationSystem.GetLocalisedValue("deal") + " " + damageToGive + " " + LocalisationSystem.GetLocalisedValue("damage") + " " + LocalisationSystem.GetLocalisedValue("to") + " " + activeBattlers[target].charName);

Now I have two questions:

  1. does anyone know the reason of this problem with the justification of words ?
  2. is there a more elegant way with TMP to add a single text string to the screen instead of reloading the whole list of strings every time I add one like I do now?

Thank you all for the time you dedicate to me even just reading these lines.

7579633--939385--LOG.png
7579633--939388--LOG in english.png

small update: I have updated TMP and Unity but it doesn’t seem to have solved the problem.

The above issue is likely related to your strings containing carriage return. These are control characters that are not visible in the Text Input of the text component but still present in your string.

It is common for people to copy paste text and end up with these control characters where they delete for instead the linefeed but leave the behind.

To find those, just move the cursor left to right in the Text Input and you should notice that it gets stuck on some invisible characters. Delete those and the issue will go away.

This is not a bug as is designed to return the pen / drawing position to the start of the line thus creating an over writting FX.

Thanks Stephan!
Tomorrow after work I’ll check what you wrote to me.

Thanks again.

ok, i managed to free myself from work and tried it right away.

As you say, scrolling the text input exactly after each scripted text entry, like:

[...] + LocalisationSystem.GetLocalisedValue("damage") + [...]

the cursor stuck on some invisible characters.

So… I have to check the LocalisationSystem.

Thanks again Stephan.

Those invisible characters are likely to be left over Carriage Returns which you should remove from the text which are the cause of the behavior you are reporting.

Hi Stephan, thanks again for all your replies!

I still have the same problem: in English it works perfectly and in Italian it inserts hidden characters.
But I don’t understand why it inserts them.

The problem unfortunately is that the text is inserted by a script based on the localization of the game.
When the script inserts the text in English there are no problems, when inserts the text in Italian instead it inserts the invisible characters.

Attached you can see a part of my csv.

This is the script that inserts the text based on localization:

    public static string GetLocalisedValue(string key)
    public static void Init()
    {
        CSVLoader csvLoader = new CSVLoader();
        csvLoader.LoadCSV();

        localisedEN = csvLoader.GetDictionaryValues("en");
        localisedIT = csvLoader.GetDictionaryValues("it");

        isInit = true;
    }

    public static string GetLocalisedValue(string key)
    {
        if (!isInit) { Init(); }

        string value = key;

        switch (language)
        {
            case Language.English:
                localisedEN.TryGetValue(key, out value);
                break;
            case Language.Italian:
                localisedIT.TryGetValue(key, out value);
                break;
        }

        return value;
    }

Instead I’m afraid the problem could be in the creation of the dictionary, for which I used a script not mine:

public class CSVLoader
    public Dictionary<string, string> GetDictionaryValues(string attributeID)
    {
        Dictionary<string, string> dictionary = new Dictionary<string, string>();

        string[] lines = csvFile.text.Split(lineSeperator);

        int attributeIndex = -1;

        string[] headers = lines[0].Split(fieldSeparator, System.StringSplitOptions.None);

        for (int i = 0; i < headers.Length; i++)
        {
            if (headers[i].Contains(attributeID))
            {
                attributeIndex = i;
                break;
            }
        }

        Regex CSVParser = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");

        for (int i = 0; i < lines.Length; i++)
        {
            string line = lines[i];

            string[] fields = CSVParser.Split(line);

            for (int f = 0; f < fields.Length; f++)
            {
                fields[f] = fields[f].TrimStart(' ', surround);
                //fields[f] = fields[f].TrimEnd(surround);
                fields[f] = fields[f].Replace("\"", ""); //or fields[f] = fields[f].Replace(surround.ToString(), "");
                //Debug.Log(fields[f]);
            }

            if (fields.Length > attributeIndex)
            {
                var key = fields[0];

                if (dictionary.ContainsKey(key)) { continue; }

                var value = fields[attributeIndex];

                dictionary.Add(key, value);
            }
        }

        return dictionary;
    }
}

What do you think?

Thanks again for all your help!

I was able to create a workaround.

I thought that the problem could only concern the last column of the CSV, since it works in English and in Italian it doesn’t.

I then added an additional column with a random character (I put a period but it also works with a null character).

You can see part of the CSV with the extra column attached.

And so it works … it’s a workaround, not a real solution … :slight_smile: