Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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
2
Question by CJCurrie · Feb 28, 2010 at 07:37 AM · guiguilayoutguistyle

How to apply multiple styles to the same line(s) of GUI text

I'd like to have a set of lines of GUI text with multiple styles in it. So long as I use only a single line of text, I can use Horizontal areas and GUILayout.Label to do coloring, but if any piece of the line flows over and "wrap"s (which is set in the style for that piece), the formatting is thrown off.

This happens because GUIlayout.Label's can't be started right after the last character in a textfield, only at the end of the text field, either to the right of it, or below it.

E.g.:

"I am the smartest person that"

[new style] "ever" [/new style]

"walked the earth, so I think."

What I want is to have something like:

"I am the smartest person that" [new style] "ever" [/new style] "walked the earth, so I think."

I could try count the number of characters and offset a manual GUI.Label (Rect(pixelCount, etc...), but that is far too inaccurate. Does anyone have a better way of doing this?

To rephrase my problem: I need a way to apply styles to portions of a string that wraps, similar to the way HTML tags work.

Comment
Add comment · Show 1
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 CJCurrie · Feb 28, 2010 at 08:03 AM 0
Share

This guy, (http://forum.unity3d.com/viewtopic.php?t=9808), used the approximation technique, with 5 pixels per character and GUILayout.Label's ins$$anonymous$$d of manual GUI.Label's.

1 Reply

· Add your reply
  • Sort: 
avatar image
3
Best Answer Wiki

Answer by CJCurrie · Mar 03, 2010 at 09:46 PM

After a little bit of work, I have a system that splits a string into a 3D array: the first dimension contains the entire string, split up into one line per element, the second dimension contains each part of line, as split up by arbitrary tags, and the third dimension contains the actual text and a cached ref to the style associated with it.

Anyway, to the example:

var notice = "Hello there. <blu>How are you? <nor>I'm fine, thank you for asking. <blu>How would you like to be my pet? <red>Oh, I'd love that. <nor>I do believe I'm going crazy as all <blu>balls <nor>else.";

var messageToReturn = ParseStyles(notice, null); // We can pass a default style here

function ParseStyles(notice : String, style : GUIStyle) { // <nor> = noticeNormal : GUIStyle // <blu> = noticeBlue : GUIStyle // <red> = noticeRed : GUIStyle

if (style != null) var curStyle = style; else // Start with normal style curStyle = noticeNormal;

var msg : Array = Array(); var leftovers : String = notice; var cont : boolean = true;

while (cont) { var container : Array = Array(); var go : boolean = true;

 // My lines will only be ~39 chars long
 if (leftovers.length &gt;= 39)
   var charsToGo : int = 39;
 else
 {
   charsToGo = leftovers.length-1;
   // We've reached the end, so do not continue
   cont = false;
 }

 var text : String = leftovers;

 while (go)
 {
   // --- Find indexes of tags within the first chunk (39 chars) of the string
   var normalIndex : int = text.IndexOf("&lt;nor&gt;",0, charsToGo);
   if (normalIndex == -1) normalIndex = 100; // Infinity doesn't work, but 100 is guaranteed to be higher than 39, our max index
   var blueIndex : int = text.IndexOf("&lt;blu&gt;",0, charsToGo);
   if (blueIndex == -1) blueIndex = 100;
   var redIndex : int = text.IndexOf("&lt;red&gt;",0, charsToGo);
   if (redIndex == -1) redIndex = 100;

   var lowest : int = Mathf.Min(normalIndex,blueIndex);
   lowest = Mathf.Min(lowest, redIndex);
   // ...etc. with all other styles compared to the previous lowest. May the lowest low win

   if (lowest &gt; 0 &amp;&amp; lowest &lt; 39)
   {
     // Put what we have so far plus the style into the end of the array
     container.Add(Array(text.Substring(0,lowest), curStyle ));

     // Remove what we added to container
     text = text.Remove(0, lowest);

     // Calculate the new style for the next iteration of the while loop. Mine starts at 1 and goes 3 because I'm evaluating what's between the &lt;___&gt;
     var sub : String = text.Substring(1, 3);
     switch (sub)
     {
       case "nor":
         curStyle = noticeNormal;
       break;
       case "blu":
         curStyle = noticeBlue;
       break;
       case "red":
         curStyle = noticeRed;
       break;
     }

     // Remove the tag characters and subtract from charsToGo.  My tags are 5 chars long
     print ("before: "+text);
     text = text.Remove(0, 5);
     charsToGo -= lowest + 5;
   }

   else
   {
     // No styles found in this segment, so put the rest of the line in and get ready for tail recursion
     if (cont)
       // We have more to do, cut at the last space.
       var lastSpace = text.LastIndexOf(" ",charsToGo); // cut it off at the last space  
     else
       // We have naught else to do, manually set lastSpace to force the whole thing into container
       lastSpace = -1;

     // Now check lastSpace
     if (lastSpace != -1)
     {
       container.Add(Array(text.Substring(0,lastSpace), curStyle ));
       leftovers = text.Remove(0, lastSpace); // Cuts everything up to lastSpace
     }
     // There is nothing more to parse
     else
     {
       container.Add(Array(text, curStyle ));
     }

     msg.Add(container);
     go = false;
   }
 }

} return msg; }

And for the GUI implementation you just need some Layouting:

GUILayout.BeginHorizontal(GUI.skin.box, GUILayout.Height(100), GUILayout.Width(760), GUILayout.ExpandHeight(true));

GUILayout.Space(30); GUILayout.BeginVertical(); GUILayout.Space(10); GUILayout.FlexibleSpace(); for (x in messageToReturn) { GUILayout.BeginHorizontal(); for (n in x) { GUILayout.Space(10); GUILayout.Label(n[0], n[1]); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.Space(1); } GUILayout.Space(10); GUILayout.FlexibleSpace(); GUILayout.EndVertical(); GUILayout.Space(30); GUILayout.FlexibleSpace();

GUILayout.EndHorizontal();

All the extra spaces and such I have in there for alignment reasons.

Now, there are some flaws to this system, most noticeably that if style changes font size some clipping may occur, there's nothing to handle words longer than the arbitrary line limit, and tags all have to be the same length (3 characters right now). These can be fixed with a little tweaking, but I figured it was complete enough to share with the community at large now.

Enjoy! If you have questions, feel free to email me at cjcurrie@blackstormsstudios.com

Comment
Add comment · Show 1 · 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 healyj28 · Nov 28, 2011 at 02:36 PM 0
Share

Could you include a Unity 3D Demo. I am new to Unity 3D and could use the help.

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.

Follow this Question

Answers Answers and Comments

1 Person is following this question.

avatar image

Related Questions

button with content in multiple colors 3 Answers

Can you use GUIStyle with GUILayout? 0 Answers

Styling an individual button in SelectionGrid 0 Answers

Why can't I get my tooltip to show only when there is a tooltip set? 2 Answers

GUI.Window error. InvalidOperationException: Hashtable.Enumerator: snapshot out of sync. 0 Answers


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