- Home /
Highlighting Parts of GUI Text
I've got a scene where the user needs to find a few items, and as they find them the original list of items highlights to show which ones have been found and which are still missing. However rather than a bullet list it's done in a sentence format because it's presented as a riddle.
How can I make certain parts of the text highlight, whilst ignoring others? I'm currently using OnGUI, so a solution working with that would be ideal but if necessary I can use 3D Text.
Update: Here's what I'm currently using to display the text, as well as some of the text that's going in to it:
GUI.Box(Rect(50,riddleBoxTop,693,riddleBoxHeight),riddleText,riddleGuiStyle);
riddleText = "Three bees, ACT changed to CAT, A ball through a maze, a fox with a hat;\n\nThe red flame on its candle, a tree in its space, A tack, two snakes, and four wheels in place.";
Answer by jahroy · Nov 11, 2011 at 12:27 AM
You don't need to use styles...
The simplest way to change the GUI color is like this:
function OnGUI () { var oldColor : Color = GUI.color; GUI.color = Color.green;
/* do some stuff */
GUI.color = oldColor;
}
I recommend breaking your sentence up into an array of strings. It sounds like it's already broken up logically based on the fact that you want to highlight different portions.
Once you've broken it up into an array, you can draw each piece of text with a separate box (changing the GUI.color as you go). Like Ray_Wilson has suggested, you can use GUIStyle.CalcSize() to figure out the width and height of each piece. This will allow you to lay the boxes out next to each other.
This really won't be that complicated at all (not as bad as it sounds)...
Ok... I'm bored. Here's some simple, un-tested example code that uses a very simple custom class namedTextItem:
var stringList : TextItem []; var startRect : Rect = Rect(0, 0, 0, 60);
function OnGUI () { var theRect : Rect = startRect; var theStyle : GUIStyle = GUI.skin.box;
/* store this for later */
var oldColor : Color = GUI.color;
for ( var thisItem : TextItem in stringList ) {
/* create a GUIContent and calculate its size */
var theContent : GUIContent = GUIContent(thisItem.text);
var theSize : Vector2 = theStyle.CalcSize(theContent);
GUI.color = thisItem.color;
theRect.width = theSize.x;
GUI.Box(theRect, theContent, theStyle);
/* set the x-value of the next box to the end of the last box */
theRect.x += theSize.width;
}
/* restore original gui color */
GUI.color = oldColor;
}
class TextItem { var text : String; var color : Color;
function TextItem ()
{
text = "";
color = Color.white;
}
}
Brilliant, just what I was looking for. I had to change theSize.width to theSize.x to get it to work initially, and now I've got a great basis to work from. Cheers jahroy!
Great. Glad it helped. I fixed the x/width thingy (oops)...
Following this up.. I've got all the boxes in, and they'll change colour as they should, but I need them to centre align.. any ideas on how I'd do this?
Here's how it's looking at the moment (I've got boxes on the objects for debugging at the moment, I'm changing them to labels later) http://img534.imageshack.us/img534/6141/riddles.jpg
The general rule for centering something is:
something.x = total.x + ( (total.width - somethingthing.width) / 2 );
So, for you it should be something like this:
firstLabel.x = ( Screen.width - totalWidthOfAllLabels ) / 2;
Cheers jahroy, I've actually got no problem doing the maths for positioning it, but the issue I'm getting is accessing the GUI labels to get their width after they've been generated.
Answer by Ray_Wilson · Nov 09, 2011 at 04:18 PM
It would really depend on how you are intending to highlight your text and also how you are composing your sentence?
For example you could highlight text by making it a different colour. To do this you would have two different styles (one for normal text and one for highlighted text) with each being a different colour. This would necessitate composing your sentence of multiple text objects (e.g. GUI.Label) and the issue would then be how do you join them together to form the sentence? The following code is in C#
// Instance two GUIStyle objects
GUIStyle TextNormal = new GUIStyle();
GUIStyle TextHighlight = new GUIStyle();
// Change the colors in the styles accordingly
TextNormal.normal.textColor = Color.white;
TextHighlight.normal.textColor = Color.yellow;
// Sentence fragments
string strNormal = "You have item: ";
string strItem = "Test Item";
// Output sentence (composition?)
GUI.Label(new Rect(10, 10, 100, 20), strNormal, TextNormal);
GUI.Label(new Rect(110, 10, 100, 20), strItem, TextHighlight);
I've updated the original, but you've spotted the big problem for me which is keeping it all held together in a sentence. I've also got another 3 of these 'riddles' for this scene alone that will need to highlight so I can't just make a static solution for this.
To be more specific about what I want for the highlight, all I want to do is make the text change colour.. if I can do this over time that'd be nice but it's not completely necessary.
I don't suppose it's possible to do the GUI and compose the text out of riddlePart1+riddlePart2+riddlePart3 (etc.) and have the GUI inherit styles for each of the parts rather than apply a style to the lot of them?
Answer by Ray_Wilson · Nov 11, 2011 at 12:00 AM
I would not recommend using inheritence to inherit GUI style information. The reason being every time you wanted to add a new style you would need to create a new base class and update or create multiple new sub-classes. As we are only talking about a different font colour you would be much better using GUIStyle in object composition and passing in the constructor.
You could overload the '+' operator to get the functionality you mention though this necessitates knowing the pixel width of a piece of text. Fortunately, GUIStyle() can calculate this for you.
Take the following class as an example and perhaps something to work on (I haven't had time to test this btw, but should hopefully just work):
public class RiddlePart
{
// A reference to the GUI style of this text
protected GUIStyle m_GUIStyle;
// The riddle fragment of text
protected string m_RiddleText;
// The text width (calculated from GUIStyle)
protected float m_TextWidth;
// The text height (calculated from GUIStyle)
protected float m_TextHeight;
// The X position of the text (screen space)
protected float m_XPos;
// The Y position of the text (screen space)
protected float m_YPos;
// ----------------
// ** Properties **
// ----------------
public float TextWidth
{
get { return m_TextWidth; }
}
public float TextHeight
{
get { return m_TextHeight; }
}
public float XPos
{
get { return m_XPos; }
}
public float YPos
{
get { return m_YPos; }
}
// ----------------
// ** Methods **
// ----------------
public RiddlePart(string RiddleText, GUIStyle Style)
{
// Store the style reference
m_GUIStyle = Style;
// Store the riddle text
m_RiddleText = RiddleText;
// Calculate text dimensions
CalculateTextDimensions();
// Default position
m_XPos = 0.0f;
m_YPos = 0.0f;
}
private void CalculateTextDimensions()
{
// We can use GUIStyle to calculate the text dimensions
m_TextWidth = m_GUIStyle.CalcSize(new GUIContent(m_RiddleText)).x;
m_TextHeight = m_GUIStyle.CalcSize(new GUIContent(m_RiddleText)).y;
}
public void SetPosition(float XPos, float YPos)
{
m_XPos = XPos;
m_YPos = YPos;
}
public void ChangeText(string NewRiddleText)
{
m_RiddleText = NewRiddleText;
CalculateTextDimensions();
}
public void RenderText()
{
// Output the text as a GUI label
GUI.Label(new Rect(m_XPos, m_YPos, m_TextWidth, m_TextHeight), m_RiddleText, m_GUIStyle);
}
// Overload the '+' operator
public static RiddlePart operator +(RiddlePart lhs, RiddlePart rhs)
{
// Update the right hand side riddle part based on the position and width/height of
// the left hand side riddle part
RiddlePart Temp = rhs;
Temp.SetPosition((lhs.XPos + lhs.TextWidth + 10.0f), lhs.YPos);
return Temp;
}
}
Adding these objects together should position them in a straight line beginning at the position of the first RiddlePart. You could create another class called 'RiddleParagraph' which is composed of 'RiddleParts' and is responsible for keeping track of line width and starting new lines and also doing the rendering of all these parts in OnGUI();
Your answer
![](https://koobas.hobune.stream/wayback/20220613035902im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Move the text in a GUI Button/Box 1 Answer
GUI.label overlapping text 1 Answer
Gui Text Script 4 Answers
Alpha not working in GUITex 0 Answers
Intro GUI Text Script... 3 Answers