Instantiated text not positioning properly

I’m instantiating a GameObject for each letter in a line of poetry so that I can create dynamic effects. The preferred width of the text is used to position the letters.

void SetupText()
    {
        // instantiate letters
        for (int i = 0, max = text.Length; i < max; ++i)
        {
            string letter = text*.ToString();*

TrickleLetterUI l = Instantiate(letterPrefab).GetComponent();
l.gameObject.transform.SetParent(lettersParent, false);
l.gameObject.name = "Letter: " + letter;
l.Setup(letter);
letters.Add(l);
}
letterPrefab.SetActive(false);

// position letters
for (int i = 0, max = text.Length; i < max; ++i)
{
TrickleLetterUI l = letters*;*
l.letterWidth = l.text.preferredWidth;

Vector3 letterPosition = lettersParent.position;
if (i > 0)
{
TrickleLetterUI prevLetter = letters[i - 1];
letterPosition = prevLetter.transform.position + (prevLetter.transform.right * ((prevLetter.letterWidth / 2) + l.letterWidth / 2));
}

l.transform.rotation = transform.rotation;
l.gameObject.transform.position = letterPosition;

l.Init(i, 0, this);
wordWidth += l.letterWidth;
}
}
The GameObjects each have Text components and are children of a Canvas with a Canvas Scaler (UI Scale Mode set to Scale with Screen Size). When my Game window is set to the reference resolution (800x600), the text is positioned correctly:
[115951-textappearreferenceresolution.png|115951]_
When my Game window is set to Maximize On Play, or sized differently than the reference resolution, the text isn’t positioned correctly:
_
[115952-textmaximizeonplay.png*|115952]*
_*
_*

Here’s the issue. When you’re creating the text, you are using world units for the position of the text. However, world units do not translate directly to screen units. Your letter size does seem to be affected by the screen resolution, but your positions are not. Thus, your UI elements get shoved into each other. Here’s some potential fixes:

  1. Decrease the size of your text on larger resolutions (if you are currently using a resizing script somewhere, decrease the amount that you are resizing it by)
  2. Add a reference to the size of the screen into the part that moves each letter to its position
  3. Use a horizontal layout group to control the distance between each letter
    One thing that would make it easier for you is to get or design a monospace font (each letter has the same width) and use that. Then, you wouldn’t have to worry about the width of each letter when placing it on the screen.

Hope this helps!

Thanks for your help @notpresident35. I ended up finding the answer here.

I just had to use localPosition instead of position when calculating and setting the distance between letters. Because localPosition comes from the RectTransform, I guess it is in screen units instead of world units. So simple!