寫在前面,最近在寫聊天系統,這里面就有一個很重要的環節就是表情與文字混排需要解決。前段時間有客戶說微信登錄,有的人微信名字含有emoji,這樣直接使用會顯示亂碼。就一起解決了。
功能
◆打包圖集
◆圖文混排
◆使用輸入法直接輸入emoji轉化顯示
怎么用?
打包圖集
點擊Tool->Bake Emoji Atlas然后設置好各個選項點擊生成即可。
顯示emoji
EmojiTextManager.Instance.SetChatTextEmoji(Emoji, "{emoji:54}Emoji表情{emoji:4}", "54|4|", emojiAtlas);
使用這個是已知emoji的id,用于聊天表情框選擇等。
EmojiTextManager.Instance.SetUITextThatHasEmoji(inputEmoji, "自行車: \U0001F6B4, 國旗: \U0001F1FA\U0001F1F8", emojiAtlas);
使用于用戶直接用輸入法輸入emoji或者獲得網絡消息中含有emoji的Unicode的時候。
EmojiTextManager.Instance.SetUITextThatHasIconByAtlas(qq, "{emoji:44}QQ{emoji:55}表情{emoji:4}", iconAtlas);
與第一個同樣,區別在于這是使用自定義的圖集。
EmojiTextManager.Instance.ConvertInputFieldText(str);
用于用戶使用輸入法輸入emoji,顯示輸入框中的表現。
填充數據
EmojiTextManager.Instance.ParseEmojiInfo(resStr);
EmojiTextManager.Instance.ParseNormalIcon(resStr);
這個需要在使用顯示圖片之前調用。
具體實現
打包圖集
設置好上面的參數。生成會把圖片文件夾中的圖片遍歷打到一個Texture2D中,然后把每張圖片在圖集的位置大小記錄下來,然后把這些數據存入xml文件中。在生成每個表情時可以設置UV來確定哪一個圖片。
圖文混排
這個功能在網上看到大多是使用的富文本加重寫Text組件來實現的。這次并沒有使用這個方案,
使用的Git上面的這個開源方案,但是這個方案有一個致命問題——只適用于一個分辨率。解決這個問題的方案是使用了NGUI中的使文字漸變的功能的原理。
public class EmojiEffect : BaseMeshEffect{
public override void ModifyMesh(VertexHelper vh){}
}
繼承與BaseMeshEffect抽象類,然后重寫ModifyMesh方法。這個方法會在你修改文字時調用。值得注意的是這個方法在編輯器下也會調用。然后使用下面的代碼獲得文字的頂點。
var vertexList=newList<UIVertex> ();
vh.GetUIVertexStream(vertexList);
這里的每一個文字有6個頂點。第一個和最后一個頂點在一個位子,以順時針增加,第三個和第四個頂點是在一起。如下示意圖:
根據頂點位子來確定表情位置,在表情的位置使用了占位符替換。
private const char emSpace = '\u2001';
根據字符串匹配判斷表情在那個字符的后面。可以看看這篇文章使用正則表達式匹配,當然也有使用直接遍歷比對。
寫在后面
這個里面還有很多沒有優化,一些東西也沒有改,等后面有時間了再來修改吧。:-)
先寫這么多吧。
嗯,一定要好好鍛煉,好好減肥!
這個是工程地址。
2017/11/24更新
這里有一個小提示,這個顯示功能需要在物體激活狀態才會正常運行,當然這里有一個特殊情況就是打開一個界面需要運行此方法,但是立馬又關閉了這個界面,會有一個小的報錯,如果是切頁類型的話,就會造成顯示錯誤。
2017/12/14更新
如果文字被截斷了,這里需要做一下判斷,不然會報空。應該是文字沒有被渲染出來,所以頂點也不會有,所以這里頂點列表中就會越界。