How to return the texts in a GUI.Box after they got modified by the Box?


I have problem with right to left languages in unity, it is my last problem and if it get fixed i can finally start my project O_O

Look at the picture: when GUI.Box wrap texts in multi lines it sort them from bottom to top (in right to left languages)! That is why i need to know how many lines are in the GUI.Box after the wraping happens then i can put them in a string and reverse them to solve the problem. (well at least i think it should solve the problem ;p)


I tried this with no result:

GUI.Box(new Rect(20, 20, Screen.width - 40, Screen.height - 40), Text);
string[] Test1 = Text.Split('

'); // Possible Problem O_O

foreach (string s in Test1)

I guess the problem is where i commented: I think i split the original text not that one which got wraped in GUI.Box?, But how can i get the Wraped/Modified text after GUI.Box did his job?

Possible problem 2 (same line i commented): GUI.Box doesn’t break lines with ‘/n’ ? :expressionless:

_ (keep in mind that i am a newbie so keep it simple! xD)

Unfortunately there’s no straight forward method to get that information. However with a few tricks it’s possible:

GUIContent singleLine = new GUIContent("H");
GUIContent doubleLine = new GUIContent("H

int GetLineCount(Rect aRect, GUIContent aText, GUIStyle aStyle)
float lineHeight = (aStyle.CalcHeight(doubleLine, 1000) - aStyle.CalcHeight(singleLine, 1000));
Vector2 pos = aStyle.GetCursorPixelPosition(aRect, aText, aText.text.Length) - aStyle.GetCursorPixelPosition(aRect, aText, 0);
return (int)(pos.y / lineHeight)+1;

This method will calculate the line count in an GUI control. Keep in mind that empty lines will count as well. If you have a newline character at the end it will count as another line.

You have to pass the same position Rect as you used for your control as well as the same GUIContent. The last parameter is the used style. If you didn’t use a custom style, you have to pass the default style for that control as string.


Rect R = new Rect(20, 20, Screen.width - 40, Screen.height - 40); 
GUI.Box(R, Text); // default style "box"
int lineCount = GetLineCount(R, new GUIContent(Text), "box");

This will return the actual line count taking wordwrap of the used style into account.

However getting the line count won’t probably help since you still don’t know where a new line starts. For this you can use a helper like this:

string[] SplitAtWordWrap(Rect aRect, string aText, GUIStyle aStyle)
    var lines = new List<int>();
    var content = new GUIContent(aText);
    float old = aStyle.GetCursorPixelPosition(aRect, content, 0).y;
    for (int i = 1; i < aText.Length; i++)
        float y = aStyle.GetCursorPixelPosition(aRect, content, i).y;
        if (y > old)
            old = y;
    if (lines.Count == 0)
        return new string[]{aText};

    string[] result = new string[lines.Count+1];
    result[0] = aText.Substring(0,lines[0]).Replace("

for(int i = 0; i < lines.Count; i++)
if (i < lines.Count-1)
result[i + 1] = aText.Substring(lines_, lines[i + 1] - lines*).Replace(”
“, “”);_
_result[i + 1] = aText.Substring(lines).Replace(”
", “”);
return result;
This method will “scan” for new lines and split the string at those positions. It will remove all “old” new line characters. Keep in mind that this need to be executed inside OnGUI. However calling it every OnGUI call would produce a huge amount of garbage and wouldn’t be very fast, so consider doing this only once or when needed.
For the generic List you need of course this line on top:
using System.Collections.Generic;
Copied the example from the comments below :wink:
string someText = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

bool executed = false;
GUIStyle boxStyle;_

void OnGUI()
executed = true; // do it only once
boxStyle = new GUIStyle(“box”);
boxStyle.wordWrap = true; // set the style to word wrap

var res = “”;
Rect r = new Rect(0, 0, 100, 200);
foreach (var line in SplitAtWordWrap(r, someText, boxStyle).Reverse())
res += line + "

someText = res;
GUI.Box(new Rect(0, 0, 100, 200), someText, boxStyle);