//Second Step: //When label is rebuilding, NGUIText processes every character of text one by one and check if a symbol or emoji matched. //If an emoji is matched, NGUIText will replace the matched string sequence with the matched symbol or emoji. //Here we can obtain the "current position" information in current label building progress(these values are localBottomLeft,localTopRight,colorTint). public RunTimeEmoji MatchEmoji(string text, int offset, int textLength) { if (!label.HasDynamicEmoji) { return null; } //Reuse showing emojis. //The most important thing is that the playing progress of emoji uv animation MUST NOT be broken after label is rebuilt. RunTimeEmoji matched = null; //Seek from showingEmojis,If matched, it will keep active and the UV playing progress will not be broken. for (int i = 0; i < showingEmojis.Count; i++) { var runTimeEmoji = showingEmojis[i]; if (runTimeEmoji.emojiData.Match(text, offset, textLength)) { matched = runTimeEmoji; showingEmojis.Remove(runTimeEmoji); break; } } //Seek from pool if (matched == null) { for (int i = 0; i < emojiPool.Count; i++) { var runTimeEmoji = emojiPool[i]; if (runTimeEmoji.emojiData.Match(text, offset, textLength)) { matched = runTimeEmoji; emojiPool.Remove(runTimeEmoji); break; } } } if (matched == null) { //The emoji haven't been created. //Create new runtime emoji. UiEmojiData matchedEmojiData = label.EmojiSlot.MatchEmoji(text, offset, textLength); if (matchedEmojiData == null) { return null; } #if UNITY_EDITOR //if sprite uvAnimation contains invalid configuration. if (!matchedEmojiData.ValidateAllSprite()) { return null; } #endif if (matchedEmojiData == null || (!matchedEmojiData.IsValid)) { return null; } matched = new RunTimeEmoji(); matched.emojiData = matchedEmojiData; matched.sprite0Data = matchedEmojiData.GetFirstSpriteData(); } return matched; }
//Step 3: //Records all the matched or unmatched emojis for post processing public void AddPreparedEmoji(RunTimeEmoji matched) { preparedEmojis.Add(matched); }