So I'm using NGUI's example typewriter script to make dialogue "type itself out" when characters talk in the game via dialogue boxes.
The dialogue's label's overflow property is set to "Shrink content," so that the dialogue will automatically shrink if it's too big. I am trying to pre-shrink the dialogue before it's rendered because a dynamic shrink is jarring. I also try to insert line breaks at appropriate locations so that a word is not shoved to the next line as it's typed out -- it automatically goes to the next line because a newline is placed right before it.
To achieve this, I do the following:
1. Give the label the message first, update it, and then record the scale value returned to influence the font size. I had to expose one variable as public first, which I didn't like to do. I don't know much about the internal workings of NGUI so this is something I thought of as an experiment.
// scale text first
// NOTE: this code assumes that the text in this label scales!
mCharDialogueMessageLabel.fontSize = 45;
mCharDialogueMessageLabel.text = message;
mCharDialogueMessageLabel.Update();
mCharDialogueMessageLabel.fontSize = Mathf.FloorToInt(mCharDialogueMessageLabel.fontSize*mCharDialogueMessageLabel.scale);
mCharDialogueMessageLabel.text = string.Empty;
mCharDialogueMessageLabel.Update();
2. After the font is scaled by NGUI (or maybe not??), insert line breaks at the correct locations
// account for line breaks at proper positions (i.e. so text doesn't wrap to next line)
// AFTER scaling text properly (since text needs to fit label first, then adjusted for word wrap)
mCharDialogueMessageLabel.UpdateNGUIText();
char[] delimiterChars = { ' ' };
string [] parts = message.Split(delimiterChars);
// add words to the modified string
StringBuilder currLine
= new StringBuilder
(); StringBuilder overallText
= new StringBuilder
(); for (int i = 0; i < parts.Length; i++)
{
string currWord = parts[i];
if (currLine.Length > 0)
currLine.Append(' ');
currLine.Append(currWord);
Vector2 printedSize = NGUIText.CalculatePrintedSize(currLine.ToString());
// this is the part where we find out if we went to next line...if so, then
// we need a line break
if ((int)printedSize.y > mCharDialogueMessageLabel.fontSize)
{
currLine.Remove(currLine.Length-currWord.Length, currWord.Length);
// remove white space at the end, otherwise it will mess up the new line
overallText.Append(currLine.ToString().TrimEnd(delimiterChars));
overallText.Append('\n');
// current line starts over with current word (since we need a new line)
currLine.Remove(0, currLine.Length);
currLine.Append(currWord);
}
}
// currline is within printed size, just add it
overallText.Append(currLine);
// overallText is then given to the typewriter
Anyway, this code seems to work for the most part even though I'm kind of shooting in the dark. But there is an example where it doesn't work, as seen in this video:
https://www.dropbox.com/s/g1wh1exumngogvj/DialogueTypingError.mov?dl=0Notice how the dialogue shrinks at the end? I want to avoid that -- it should be scaled appropriately beforehand. I believe that if I print out the fontscale after the typewriter is finished, it's different compared to the scale computed above. Anyway, just wondering if there is a reasonable solution to this or if this has been done.