Author Topic: Typewriter text that fits label beforehand  (Read 6871 times)

prinky

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 13
    • View Profile
Typewriter text that fits label beforehand
« on: January 23, 2015, 12:12:59 AM »
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.
  1.   // scale text first
  2.   // NOTE: this code assumes that the text in this label scales!
  3.   mCharDialogueMessageLabel.fontSize = 45;
  4.   mCharDialogueMessageLabel.text = message;
  5.   mCharDialogueMessageLabel.Update();
  6.   mCharDialogueMessageLabel.fontSize =     Mathf.FloorToInt(mCharDialogueMessageLabel.fontSize*mCharDialogueMessageLabel.scale);
  7.   mCharDialogueMessageLabel.text = string.Empty;
  8.   mCharDialogueMessageLabel.Update();
  9.  

2. After the font is scaled by NGUI (or maybe not??), insert line breaks at the correct locations
  1.     // account for line breaks at proper positions (i.e. so text doesn't wrap to next line)
  2.     // AFTER scaling text properly (since text needs to fit label first, then adjusted for word wrap)
  3.     mCharDialogueMessageLabel.UpdateNGUIText();
  4.     char[] delimiterChars = { ' ' };
  5.     string [] parts = message.Split(delimiterChars);
  6.     // add words to the modified string
  7.     StringBuilder currLine = new StringBuilder();
  8.     StringBuilder overallText = new StringBuilder();
  9.     for (int i = 0; i < parts.Length; i++)
  10.     {
  11.       string currWord = parts[i];
  12.       if (currLine.Length > 0)
  13.         currLine.Append(' ');
  14.       currLine.Append(currWord);
  15.  
  16.       Vector2 printedSize = NGUIText.CalculatePrintedSize(currLine.ToString());
  17.       // this is the part where we find out if we went to next line...if so, then
  18.       // we need a line break
  19.       if ((int)printedSize.y > mCharDialogueMessageLabel.fontSize)
  20.       {
  21.         currLine.Remove(currLine.Length-currWord.Length, currWord.Length);
  22.         // remove white space at the end, otherwise it will mess up the new line
  23.         overallText.Append(currLine.ToString().TrimEnd(delimiterChars));
  24.         overallText.Append('\n');
  25.         // current line starts over with current word (since we need a new line)
  26.         currLine.Remove(0, currLine.Length);
  27.         currLine.Append(currWord);
  28.       }
  29.     }
  30.     // currline is within printed size, just add it
  31.     overallText.Append(currLine);
  32.     // overallText is then given to the typewriter
  33.  

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=0

Notice 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.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Typewriter text that fits label beforehand
« Reply #1 on: January 23, 2015, 09:50:42 PM »
Why use shrink to fit with something like this? You should just keep it at something else -- something that doesn't change the size of the text. You can pre-wrap the text easily by simply turning on TypeWriterEffect.keepFullDimensions.

prinky

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 13
    • View Profile
Re: Typewriter text that fits label beforehand
« Reply #2 on: January 24, 2015, 12:44:08 AM »
Why use shrink to fit with something like this? You should just keep it at something else -- something that doesn't change the size of the text. You can pre-wrap the text easily by simply turning on TypeWriterEffect.keepFullDimensions.

I'm using shrink because sometimes the dialogue might be too long for the label.

I could keep the text a certain size that works for all lengths of dialogue. I suppose that would be more consistent. However I prefer to keep the text bigger for general readability and shrink it just in case the dialogue is too long.

Am I trying to solve a problem that's too difficult? I could just keep the text size small by default and not worry about shrinking as a last resort.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Typewriter text that fits label beforehand
« Reply #3 on: January 25, 2015, 01:05:37 AM »
That's what I would advise, yes. Keep the font at its decently small size and don't worry about shrinking. The typewriter script works best with that kind of text.

prinky

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 13
    • View Profile
Re: Typewriter text that fits label beforehand
« Reply #4 on: January 25, 2015, 02:30:48 PM »
That's what I would advise, yes. Keep the font at its decently small size and don't worry about shrinking. The typewriter script works best with that kind of text.

Good point, I'll do that.