I was trying to make individual words in a label tappable, for the purposes of highlighting them as they are tapped, and playing the audio for that word. Colour me amazed to find NGUI already had a function for this! However, it seems to throw exceptions when you tap on spaces in the label. I was able to get around it with a dirty try/catch, but perhaps it needs fixing, or I am just missing something? I'll paste my function for reference, if you're interested! (heavily commented for some new-to-Unity devs joining me soon.) I'm not sure I can post any code from UILabel.cs where I believe the problem is, so I'll leave that out.

public void NarrationTapped()
{
HighlightWord(-1);//passing -1 for the word index should clear any highlighting on the string.
Vector2 screenPos = Input.mousePosition; //grab screen coords where you tapped
Camera cam = NGUITools.FindCameraForLayer (gameObject.layer);
Vector3 worldPos = cam.ScreenToWorldPoint (screenPos);//fancy unity convert screen coords to world coords
int charIndex;
try{ //have to wrap this whole thing in a try/catch because NGUI throws exceptions when tapping on space characters...
charIndex = narrationTextLbl.GetCharacterIndexAtPosition(worldPos);//get the index into the string for the character you tapped.
string oldText = narrationTextLbl.text;//copy the page text locally so we can mess with it.
if(charIndex != -1 && charIndex < oldText.Length)
{
if(narrationTextLbl.GetWordAtCharacterIndex(charIndex) != " ")
{
string hexBlue = @"[0000ff]";
string endColorTag = "[-]";
int linkStart = oldText.LastIndexOf(' ', charIndex) + 1; //find the char index for the first character of the selected word
if(linkStart==0) linkStart+= hexBlue.Length;//if you hit the first word, we have to skip the initial bit of BBcode that makes the text black.
int linkEnd = oldText.IndexOf(' ', charIndex);//gets the char index for the end of the selected word.
if (linkEnd == -1) linkEnd = oldText.Length;
if (linkStart != linkEnd)
{
oldText = oldText.Insert(linkStart, hexBlue);//insert the blue BBcode before the word.
oldText = oldText.Insert((linkEnd+hexBlue.Length), "[-]");//and close the BBcode tag
}
narrationTextLbl.text = oldText;//then set the text back to the label
string word = narrationTextLbl.GetWordAtCharacterIndex(charIndex).ToUpper();//get the word now, and uppercase it for the filename.
string fileName = System.Text.RegularExpressions.Regex.Replace(word, "[?!,.;:]", "");//remove punctuations (add to that array if we missed a punctuation type!)
AudioClip snd
= (AudioClip
)Resources
.Load("Words/" + fileName,
typeof(AudioClip
));//load the sound clip for the word narrationAudio.clip = snd;//set it
narrationAudio.Play();//play it!
}
}
}
catch{
Debug.Log ("you probably clicked on a space");
}
}
edit: here is the exception thrown as well:
ArgumentOutOfRangeException: Cannot be negative.
Parameter name: length
System.String.Substring (Int32 startIndex, Int32 length) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System/String.cs:348)
UILabel.GetWordAtCharacterIndex (Int32 characterIndex) (at Assets/NGUI/Scripts/UI/UILabel.cs:1286)
NarrationLoader.NarrationTapped () (at Assets/Scripts/NarrationLoader.cs:115)