感受使用Unity以後總能看到各類各樣解決混排的方案,只能說明Unity不夠體恤下情啊。這篇文章主要講一下我的在使用過程當中方案選擇和優化過程,已作記錄。順便提下,開源不少意味着坑,仍是要開實際需求。html
1 TextMeshPro
Unity 最近公佈收購了TextMeshPro而且免費開源給你們使用,估計還須要幾個小版本纔會徹底融合到Unity中或者保持如今的狀態。TextMeshPro支持效果豐富,兼容如今UI層級等,性能也能夠知足移動端,可是很糾結的是:git
基於上面亮點,最後我仍是沒有采用這種方案,若是Unity考慮融合進來,建議修改下字庫的使用方式。github
2 文字和圖片獨立渲染編程
最後採用了文字富文本保留空間,圖片根據位置單獨渲染的方案,主要的緣由在於性能可控以及如今代碼還算比較完善(這裏徹底是個坑)。這個版本最初的源碼:https://code.csdn.net/qq992817263/uguitextpro/tree/master緩存
2.1 基本思想數據結構
參考文章
Unity Text 插入圖片,這篇文章是基本的實現方式,後面CSDN「神碼編程」也就在這基礎上作了幾處擴展和一些文章分享編輯器
2.2 代碼實現思路測試
提早生成sprite區域信息,若是是一個系列的表情則根據sprite名字進行區分,固然後面也根據名字進行保留和查找。如angry_0\angry_1\angry_2\angry_3 , die_0/die_1/die_2/die_4/die_5/die_6字體
繼承Text組件,重寫OnPopulateMesh以及字符解析,維護裏面圖片位置、頂點等信息
表情管理器:記錄全部Text中圖片(有效的)位置、紋理、頂點信息的索引關係,由數據變化時生成須要的Mesh信息並提交
SpriteAsset 管理器:管理圖片中全部Text中使用的圖片資源加載以及sprite位置、名字信息。
最初的源碼看似可用,可是在手機端ListView滾動狀況下直接掉到20幀一下,即便在靜態100個表情同時更新的境況下效率也很難使人滿意。因此.................差很少用了一週時間爬各類坑,下面是一些主要的記錄:
代碼中在解析字符中基本每次都在new數據,包括解析字符、計算圖片位置、更新圖片Mesh等都存在很嚴重的GC,看上圖就能夠看到滾動中若是頻繁建立的問題。
優化思路:
啓動時讀取配置信息,並簡歷sprite名字和信息的對應Dictionary,加快查找。固然也能夠直接以Dictionary結構進行序列化,就能夠節省這部分空間和時間,待優化。
原始版本中有效Sprite 列表時經過List的形式進行管理,每次任一個Text的變化(enabled,posotion等)都會將這個列表清除並從新將有效Text中的有效Sprite添加到列表中來。這種方式若是在相似ListView等一直會變化的組件中就會產生沒必要要的CPU開銷。
優化思路:
這種方式避免在頻繁更新中沒必要要的列表清除操做以及對SpriteManager lateUpdate的影響
最初的版本採用對SpriteList遍歷的形式逐個將triangles、uv、vertices 賦值到新建立的緩存中,再扔給iMesh去提交。在ListView快速移動時這部分的時間佔用就很誇張了。
優化思路:
原始版本可能時做者計算錯誤了,清除亂碼的UV位置其實只須要向後4個便可,可是也原始版本是按4 * Length(標籤長度)來計算,這項的CPU佔用率特別高。
原始版本時在SpriteUpdate中每隔固定時間更新表情的索引(若是有)並從新更新Sprite Mesh內容。會產生一個問題:每種類型表情動畫圖片的數目不同,那就很難保證每一個動態表情都很天然的播放。提升更新的間隔意味着有些表情像發飆同樣
優化思路:
每類型的表情中單獨存放其時間間隔以及已經運行的時間,在Update中根據各自的狀況進行更新。
原始代碼中是在Text :SetVerticesDirty()中進行ParseText的操做並依賴SpriteManager中LaterUpdate更新圖片的Mesh數據,產生的問題:
優化思路:
對應的還有編輯器、數據結構、貼圖資源管理等的優化
支持 "[xxxxx]"來替代
方便單個Canvas下多個層級,讓Text 能夠直接設置SpriteManager或者找最近的一個。
(1)下劃線解析和超連接解析都是基於字符位置對應實際字符頂點位置
(2)字符串解析
(3)圖片Mesh
(4)多張sprite Asset
測試方式,屏幕中160個動畫表情的狀況,在ListView中快速滾動下進行測試的性能曲線(主要時CPU);
優化前
優化後
原生Text, 有佔位符,無表情
採用這種方案各類緣由都有,有好處也有弊端,就像層級問題,解決起來會有點頭痛。通過一段時間優化勉強能夠在移動端知足需求,不過還有不少能夠繼續優化的空間。
GITHUB工程文件:https://github.com/carlosCn/Unity-EmojiText
百度網盤資源:http://pan.baidu.com/s/1geZuVNd
歡迎繼續補充。