• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
Question by Mohammad Alavi · Nov 06, 2014 at 08:52 AM · guibox

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

Hi

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)

alt text

I tried this with no result:

 GUI.Box(new Rect(20, 20, Screen.width - 40, Screen.height - 40), Text);
         
 string[] Test1 = Text.Split('\n'); // Possible Problem O_O

 foreach (string s in Test1)
 {
 Debug.Log(s);
 }

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' ? :|

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

wrap.png (229.1 kB)
Comment
Bunny83

People who like this

1 Show 0
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
Best Answer

Answer by Bunny83 · Nov 06, 2014 at 09:34 AM

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\nH");
 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.

Example:

 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.

edit
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;
             lines.Add(i);
         }
     }
     if (lines.Count == 0)
         return new string[]{aText};

     string[] result = new string[lines.Count+1];
     result[0] = aText.Substring(0,lines[0]).Replace("\n","");
     for(int i = 0; i < lines.Count; i++)
     {
         if (i < lines.Count-1)
             result[i + 1] = aText.Substring(lines[i], lines[i + 1] - lines[i]).Replace("\n", "");
         else
             result[i + 1] = aText.Substring(lines[i]).Replace("\n", "");
     }
     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;

edit
Copied the example from the comments below ;)

 string someText = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n";
 bool executed = false;
 GUIStyle boxStyle;
 
 void OnGUI()
 {
     if(!executed)
     {
         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 + "\n";
         }
         someText = res;
     }
     GUI.Box(new Rect(0, 0, 100, 200), someText, boxStyle);
 }
Comment
Mohammad Alavi

People who like this

1 Show 10 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Nov 06, 2014 at 10:03 AM 1
Share

@mohammad-alavi: That's what i thought, so i made another method ;)

avatar image Bunny83 · Nov 08, 2014 at 03:14 PM 1
Share

@mohammad-alavi: Well, are you sure that you have "wordwrap" set to true for your box style? It works just fine for me. Keep in mind you have to execute this method from inside OnGUI. Doing it in Start or Awake won't work.

Maybe it behaves differently for a right-to-left font. As far as i remember Unity doesn't support RTL out of the box. Maybe that has already been implemented, if not you might want to look for an RTL converter in the assetstore. There are a few afaik.

avatar image Bunny83 · Nov 08, 2014 at 03:41 PM 1
Share

This works for me:

 string someText = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n";
 bool executed = false;
 GUIStyle boxStyle;
 
 void OnGUI()
 {
     if(!executed)
     {
         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 + "\n";
         }
         someText = res;
     }
     GUI.Box(new Rect(0, 0, 100, 200), someText, boxStyle);
 }

The actual GUI.Box wouldn't need the modified boxStyle since each line should now be short enough to fit into the rect. To use the Reverse method you have to add using System.Linq; at the top. For me it displays the text correctly wordwrapped but the lines in reverse order.

Of course it isn't a RTL text but i tried some random arabic text and it seems to work as well. At least the way you explained it in your question. Unfortunately I don't know anything about any of those RTL languages so i can't tell if it's correct :)

avatar image Bunny83 · Nov 10, 2014 at 08:41 PM 1
Share

@mohammad-alavi:
Well, you just have to split your text before you use SplitAtWordWrap. So just split your text at new line characters into a seperate string for each paragraph. Now you can "reverse" each paragraph on it's own and finally just "concat" the result back together.

To split a string at the line feed character use:

 string[] paragraphs = text.Split('\n');
avatar image Bunny83 · Nov 13, 2014 at 06:26 PM 1
Share

@mohammad:
Hmm, sorry but i'm confused a bit, probably because i don't know how you read such a RTL text ^^. In your questions picture you just showed the two lines reversed and with the empty space in the top line (I guess you read from bottom to top, right?).

I'm not sure which lines you want to join together? If i got that right the paragraphs should be ordered from top to bottom but in each paragraph the lines should be swaped. So each paragraph is handled on it's own, or do you want to join parts of two different paragraphs together?

Each paragraph must not contain any new line characters. It should be one line of text, otherwise you can't split the paragraphs at that character.

I guess the word wrapping feature of Unity's GUI system might not be the best choice as it simply doesn't support RTL text. What you could do manually is splitting the whole paragraph manually into words (split at the " " (space) character), check the legnth of each word (using CalcSize with only one word + a space) and add up the x size value until you reach the size of your rect. Then you can simply rejoin the words and construct seperate lines yourself. There you have full control of the order of the words in a paragraph and which will be the first line.

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

How to change the font and size of a text in a gui box? 1 Answer

on button hover box shows 2 Answers

gui box visibility 0 Answers

How to create GUIBox with tools? 0 Answers

Fading between scenes 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges