How to split up a Text Object into Text Objects of size 1 char at the exact same position?

Hi ppl,

so I’m basically trying to build a highlighting mechanic for texts as it would work on any OS.
In pseudo code something like

If (user holds down MouseButton(0))
    hightlight every char the mouse hovers over until MouseButton(0)Up

or

OnMouseButton(0)Down {
store MousePosition
}
OnMouseButton(0)Up {
highlight every char between stored position and this MousePosition
}

Now as I see things I need either one of these:

  • every character is a text object of its own with its own collider
  • a method that translates the positions of the mouse into positions in the text object, creates 3 substrings (of the stuff before the highlighted part, the highlighted part itself and the stuff after that) and displays them in the same positioning as before

The second one seems pretty complicated so I tackled the first one. For usability I want to be able to enter text in the text component of my text object (I’m in Unity Editor right now) and when I hit start I want my method to cut the text into substrings of exactly 1 char.
While this is no problem, I don’t know how to position the generated chars so they match their previous positions exactly no matter what font size I chose.

What I need is an algorithm that gives me an offset for the position depending on font size and width of that particular character in the given font.

Any ideas on that?

What I currently have works to create those 1 char text objects with the same font, size etc. as the given text. I use 3D Text instead of UI Text but for no particular reason.

Transform textParent; //this is simply an empty GameObject holding all my text objects

    void Start () {
        textParent = GameObject.Find("Texts").transform;

        for (int i = 0; i < textParent.childCount; i++)
        {
            CreateObjectForEveryChar(textParent.GetChild(i));
        }
    }

void CreateObjectForEveryChar(Transform textVessel)
    {
        TextMesh textMesh = textVessel.GetComponent<TextMesh>();
        char[] text;
        float offset = 0f;

        if (textVessel.GetComponent<TextMesh>() == null)
        {
            Debug.Log("Error - no TextMesh found on " + textVessel.ToString());
        }
        else
        {
            text = textMesh.text.ToCharArray();
            for(int i = 0; i < text.Length; i++)
            {
                GameObject character = (GameObject) Instantiate(textVessel.gameObject, textVessel.localPosition + Vector3.left * offset, textVessel.localRotation);
                //character.transform.SetParent(textVessel); //this actually makes unity freeze everytime I hit play so I'm skipping that for now
                character.GetComponent<TextMesh>().text = text*.ToString();*

//offset += ??;
}
}
}

You will need to look at the font’s specific characters in order to make the appropriate computations.

You can get the font from the TestMesh class, via Unity - Scripting API: TextMesh.font

Once you have the font you can get each character’s alignment and layout data, in that font, using Unity - Scripting API: Font.GetCharacterInfo

The results are provided in the form of a Unity - Scripting API: CharacterInfo structure, which should have all the information you need to compute positions.

Don’t forget about other things that might affect positions, such as the alightment and anchor options, in the TextMesh. Particularly important for this, will be fontSize (watch out for zero values)!

Edit: oh yeah, just incase that isn’t complex enough: Text Meshes can also use markup! e.g. < B >Bold Text< /B >

Did you check Fully Flexible UI Text | GUI Tools | Unity Asset Store?
You can separate each UI Text in as many UI Texts as the number of characters.
It even take care of rich text feature.