態(tài)字體與Fallback配置實(shí)戰(zhàn))
1. 項(xiàng)目背景與核心需求拆解Unity項(xiàng)目做到中期UI界面開(kāi)始批量鋪文字的時(shí)候十有八九會(huì)遇到一個(gè)很尷尬的情況用默認(rèn)的Text組件顯示中文字邊緣糊得像被水泡過(guò)放大一點(diǎn)全是鋸齒尤其是做移動(dòng)端或者需要多語(yǔ)言切換的項(xiàng)目字體資源動(dòng)輒十幾MB打包出來(lái)包體直接爆炸。這時(shí)候大部分人的第一反應(yīng)就是換TextMeshPro畢竟它是Unity官方推薦的文本渲染方案基于SDFSigned Distance Field有向距離場(chǎng)技術(shù)任意字號(hào)下都能保持邊緣銳利而且一套字體圖集能覆蓋大量字符包體控制比傳統(tǒng)Font紋理方案好太多。但問(wèn)題馬上就來(lái)了——新建一個(gè)TextMeshPro的Text對(duì)象輸入中文屏幕上要么是一片空白要么是一堆方塊豆腐塊。這不是Bug而是TextMeshPro默認(rèn)只帶了一個(gè)拉丁字符集的字體資源中文字符根本不在它的圖集里。這個(gè)項(xiàng)目要解決的核心問(wèn)題就一個(gè)讓TextMeshPro正確顯示中文并且在不同字號(hào)、不同分辨率下都保持清晰同時(shí)把字體資源體積控制在可接受范圍內(nèi)。這個(gè)需求看起來(lái)簡(jiǎn)單但實(shí)際動(dòng)手會(huì)發(fā)現(xiàn)里面有不少坑。比如字體圖集該選什么模式、字符集該包含哪些字、動(dòng)態(tài)字體和靜態(tài)字體怎么選、Fallback機(jī)制怎么配、打包后為什么又變回方塊了……這些問(wèn)題在官方文檔里散落在各個(gè)角落新手很容易卡住。這篇文章適合所有正在用Unity做中文項(xiàng)目、被TextMeshPro中文顯示問(wèn)題折騰過(guò)的開(kāi)發(fā)者不管你是剛接觸Unity的新手還是已經(jīng)用過(guò)TMP但沒(méi)深究過(guò)字體管線(xiàn)配置的老手都能從下面的實(shí)操記錄里找到可以直接抄作業(yè)的方案。我自己的項(xiàng)目是一個(gè)2D橫版解謎游戲UI文字量中等大概常用漢字兩三千個(gè)加上一些特殊符號(hào)和數(shù)字需要支持動(dòng)態(tài)對(duì)話(huà)文本。下面就把整個(gè)配置過(guò)程、參數(shù)選擇的理由、踩過(guò)的坑和最終穩(wěn)定的方案完整記錄下來(lái)。2. TextMeshPro中文顯示的核心原理與方案選型2.1 為什么TMP默認(rèn)不顯示中文TextMeshPro的工作方式和傳統(tǒng)Text組件有本質(zhì)區(qū)別。傳統(tǒng)Text組件依賴(lài)Unity的Font資源運(yùn)行時(shí)動(dòng)態(tài)生成字形紋理每個(gè)字號(hào)都會(huì)重新光柵化所以中文能顯示但效果差、內(nèi)存占用高。TMP則是在導(dǎo)入字體時(shí)就把字形預(yù)渲染到一張圖集Atlas里運(yùn)行時(shí)通過(guò)UV坐標(biāo)從圖集采樣配合SDF數(shù)據(jù)實(shí)現(xiàn)任意縮放。關(guān)鍵就在這里TMP的字體資源Font Asset在創(chuàng)建時(shí)默認(rèn)只包含ASCII字符集大約95個(gè)可見(jiàn)字符加一些控制符。中文字符有上萬(wàn)個(gè)不可能全部預(yù)渲染到一張圖集里所以默認(rèn)的Font Asset里根本沒(méi)有中文字形數(shù)據(jù)顯示出來(lái)自然就是空白或方塊。要解決這個(gè)問(wèn)題本質(zhì)上就是讓TMP的Font Asset包含你需要的中文字形。有兩種思路一是把常用漢字全部預(yù)渲染成靜態(tài)圖集二是用動(dòng)態(tài)字體資源在運(yùn)行時(shí)按需生成字形。兩種方案各有優(yōu)劣下面詳細(xì)對(duì)比。2.2 靜態(tài)字體圖集 vs 動(dòng)態(tài)字體資源靜態(tài)字體圖集的做法是在Font Asset創(chuàng)建時(shí)指定一個(gè)字符集文件比如包含3500常用漢字的txtTMP會(huì)把這些字全部渲染到一張或多張圖集紋理上。優(yōu)點(diǎn)是運(yùn)行時(shí)性能穩(wěn)定不需要?jiǎng)討B(tài)生成適合字符集固定的場(chǎng)景。缺點(diǎn)是圖集紋理可能很大3500個(gè)漢字在512x512的圖集上大概需要4-6張顯存占用不小而且如果遇到字符集外的生僻字依然顯示不出來(lái)。動(dòng)態(tài)字體資源的做法是Font Asset的Atlas Population Mode設(shè)為Dynamic運(yùn)行時(shí)遇到圖集里沒(méi)有的字符自動(dòng)從源字體文件比如TTF/OTF中提取字形并添加到圖集。優(yōu)點(diǎn)是字符集無(wú)限擴(kuò)展包體只需要帶一個(gè)源字體文件顯存按需增長(zhǎng)。缺點(diǎn)是首次顯示某個(gè)字時(shí)有輕微的性能開(kāi)銷(xiāo)而且如果圖集滿(mǎn)了需要擴(kuò)容可能觸發(fā)一次卡頓。我的項(xiàng)目最終選擇了動(dòng)態(tài)模式為主、靜態(tài)預(yù)渲染常用字為輔的混合方案。具體來(lái)說(shuō)把最常用的500個(gè)漢字預(yù)渲染到圖集里保證啟動(dòng)后UI文字立刻顯示其余字符走動(dòng)態(tài)生成。這樣既避免了啟動(dòng)時(shí)大量動(dòng)態(tài)生成的卡頓又保留了字符擴(kuò)展能力。2.3 字體文件的選擇與授權(quán)注意中文字體文件的選擇直接影響最終效果和包體大小。常見(jiàn)的免費(fèi)可商用中文字體有思源黑體、思源宋體、阿里巴巴普惠體等這些字體字符集完整、字重豐富適合游戲項(xiàng)目。但要注意字體文件本身有版權(quán)商用項(xiàng)目必須確認(rèn)授權(quán)范圍。另外字體文件體積差異很大完整的思源黑體OTF大概16MB如果直接打進(jìn)包體對(duì)移動(dòng)端來(lái)說(shuō)負(fù)擔(dān)不小。這里有個(gè)優(yōu)化技巧可以用字體子集化工具把項(xiàng)目實(shí)際用到的字符提取出來(lái)生成一個(gè)精簡(jiǎn)的字體文件。比如項(xiàng)目只用到了3500常用字加一些符號(hào)子集化后的TTF可能只有2-3MB。但子集化有個(gè)風(fēng)險(xiǎn)——如果后續(xù)劇情文本出現(xiàn)了子集外的字就會(huì)顯示異常。所以子集化時(shí)最好留足余量或者保留動(dòng)態(tài)回退機(jī)制。注意字體文件的授權(quán)條款一定要仔細(xì)看有些字體免費(fèi)用于個(gè)人項(xiàng)目但商用需要購(gòu)買(mǎi)授權(quán)有些則完全開(kāi)源可商用。項(xiàng)目上線(xiàn)前務(wù)必確認(rèn)清楚避免法律風(fēng)險(xiǎn)。3. 完整實(shí)操流程從零配置TMP中文顯示3.1 準(zhǔn)備工作導(dǎo)入字體文件與創(chuàng)建Font Asset第一步把選好的中文字體文件TTF或OTF拖進(jìn)Unity項(xiàng)目的Assets文件夾建議放在Assets/Fonts目錄下統(tǒng)一管理。導(dǎo)入后選中字體文件在Inspector面板確認(rèn)Unity能正確識(shí)別Font Size和Character選項(xiàng)保持默認(rèn)即可。第二步創(chuàng)建TMP的Font Asset。右鍵點(diǎn)擊字體文件選擇Create TextMeshPro Font Asset。這時(shí)候會(huì)彈出一個(gè)創(chuàng)建窗口關(guān)鍵參數(shù)如下Source Font File自動(dòng)指向你選中的字體文件不用改。Sampling Point Size采樣點(diǎn)大小默認(rèn)Auto。這個(gè)值決定了SDF圖集的基礎(chǔ)分辨率Auto會(huì)根據(jù)字體文件的默認(rèn)大小自動(dòng)選擇。我實(shí)測(cè)下來(lái)中文字體建議手動(dòng)設(shè)為64或72太小會(huì)導(dǎo)致小字號(hào)下筆畫(huà)粘連太大則圖集占用暴增。Padding字形周?chē)牧舭紫袼啬J(rèn)9。這個(gè)值影響SDF邊緣的平滑范圍中文筆畫(huà)密集建議保持9或適當(dāng)增加到10-12避免相鄰字形的SDF數(shù)據(jù)互相干擾。Atlas Resolution圖集分辨率默認(rèn)512x512。中文動(dòng)態(tài)字體建議設(shè)為1024x1024給動(dòng)態(tài)生成留足空間。Atlas Population Mode這是核心參數(shù)。選Static就是靜態(tài)圖集選Dynamic就是動(dòng)態(tài)生成。我選的是Dynamic配合下面的字符集預(yù)渲染。Character Set字符集選擇。如果選Dynamic模式這里可以選Custom Character Set然后指定一個(gè)包含常用漢字的txt文件TMP會(huì)在創(chuàng)建時(shí)把這些字預(yù)渲染進(jìn)去。創(chuàng)建完成后TMP會(huì)生成一個(gè)Font Asset文件.asset里面包含了圖集紋理和字形數(shù)據(jù)。這時(shí)候把它拖到場(chǎng)景里TextMeshPro的Font Asset槽位輸入中文測(cè)試應(yīng)該就能看到字了。3.2 字符集文件的制作與預(yù)渲染策略字符集文件就是一個(gè)純文本文件里面包含你希望預(yù)渲染的所有字符不需要分隔符TMP會(huì)自動(dòng)去重。我用的方案是從常用漢字表中提取前500字加上數(shù)字、英文字母、常用標(biāo)點(diǎn)符號(hào)保存為charset_common.txt。制作字符集文件時(shí)有個(gè)細(xì)節(jié)文件編碼必須是UTF-8否則TMP讀取時(shí)會(huì)出現(xiàn)亂碼。另外字符之間不要加空格或換行以外的分隔符直接連續(xù)寫(xiě)就行。比如的一是了我不人在他有這個(gè)上們來(lái)到時(shí)大地為子中你說(shuō)生國(guó)年著就那和要她出也得里后自以會(huì)家可下而過(guò)天去能對(duì)小多然于心學(xué)么之都好看起發(fā)當(dāng)沒(méi)成只如事把還用第樣道想作種開(kāi)美總從無(wú)情己面最女但現(xiàn)前些所同日手又行意動(dòng)方期它頭經(jīng)長(zhǎng)兒回位分愛(ài)老因很給名法間斯知世什兩次使身者被高已親其進(jìn)此話(huà)常與活正感這500個(gè)字覆蓋了日常文本大約80%的用字頻率預(yù)渲染后啟動(dòng)時(shí)UI文字基本秒顯。剩下的字走動(dòng)態(tài)生成首次出現(xiàn)時(shí)會(huì)有幾毫秒的延遲但實(shí)際體驗(yàn)中幾乎感知不到。實(shí)操心得字符集文件不要貪多預(yù)渲染太多字會(huì)導(dǎo)致Font Asset文件巨大而且Unity編輯器打開(kāi)時(shí)會(huì)變卡。500-1000個(gè)常用字是比較平衡的選擇。如果項(xiàng)目文本量特別大可以考慮按章節(jié)拆分字符集但那樣管理成本會(huì)上升。3.3 動(dòng)態(tài)字體資源的參數(shù)調(diào)優(yōu)動(dòng)態(tài)模式下Font Asset的Atlas Resolution和Multi Atlas Textures選項(xiàng)很關(guān)鍵。Atlas Resolution決定了單張圖集的大小Multi Atlas Textures開(kāi)啟后當(dāng)一張圖集滿(mǎn)了會(huì)自動(dòng)創(chuàng)建新圖集。我的設(shè)置是參數(shù)值理由Atlas Resolution1024x1024平衡顯存占用和擴(kuò)容頻率Multi Atlas Textures開(kāi)啟避免圖集滿(mǎn)后字符無(wú)法顯示Atlas Population ModeDynamic運(yùn)行時(shí)按需生成Clear Dynamic Data On Build開(kāi)啟打包時(shí)清空編輯器里生成的動(dòng)態(tài)數(shù)據(jù)減小包體Padding10中文筆畫(huà)密集留足SDF邊緣空間這里重點(diǎn)說(shuō)一下Clear Dynamic Data On Build。這個(gè)選項(xiàng)默認(rèn)是關(guān)閉的如果不開(kāi)啟編輯器里運(yùn)行時(shí)動(dòng)態(tài)生成的字形數(shù)據(jù)會(huì)被打包進(jìn)最終包體導(dǎo)致包體無(wú)謂增大。開(kāi)啟后打包時(shí)會(huì)清空這些數(shù)據(jù)運(yùn)行時(shí)重新按需生成。代價(jià)是首次運(yùn)行某個(gè)字時(shí)會(huì)有生成開(kāi)銷(xiāo)但包體更干凈。另外Sampling Point Size在動(dòng)態(tài)模式下也很重要。它決定了SDF圖集的基礎(chǔ)分辨率值越大字形邊緣越精細(xì)但圖集占用也越大。我試過(guò)32、64、72三個(gè)值32在小字號(hào)下筆畫(huà)會(huì)糊72在圖集占用上比64多出約30%最終選了64作為平衡點(diǎn)。3.4 Fallback字體鏈的配置Fallback機(jī)制是TMP的一個(gè)強(qiáng)大功能當(dāng)主Font Asset里找不到某個(gè)字符時(shí)自動(dòng)到Fallback列表里查找。這對(duì)于中文項(xiàng)目特別有用因?yàn)槟憧梢园延⑽淖煮w作為主字體中文字體作為Fallback這樣英文用更美觀(guān)的字體渲染中文自動(dòng)回退到中文字體。配置方法選中主Font Asset在Inspector面板找到Fallback Font Assets列表把中文字體Asset拖進(jìn)去。可以配置多個(gè)FallbackTMP會(huì)按順序查找。比如主字體某英文無(wú)襯線(xiàn)字體用于數(shù)字和英文Fallback 1思源黑體Regular用于中文正文Fallback 2思源黑體Bold用于加粗中文Fallback 3某符號(hào)字體用于特殊圖標(biāo)這樣配置后TextMeshPro組件里只需要指定主字體遇到中文會(huì)自動(dòng)走Fallback不需要手動(dòng)切換字體資源。注意Fallback鏈的查找順序是從上到下所以要把最常用的字體放在前面。另外Fallback字體也必須是TMP的Font Asset格式不能直接拖TTF文件。4. 常見(jiàn)問(wèn)題排查與避坑指南4.1 中文顯示為方塊或空白這是最常見(jiàn)的問(wèn)題原因通常有三個(gè)一是Font Asset里根本沒(méi)有中文字形數(shù)據(jù)二是字符集文件編碼不對(duì)導(dǎo)致TMP沒(méi)讀到三是TextMeshPro組件的Font Asset槽位沒(méi)指定正確的字體。排查步驟首先確認(rèn)Font Asset的Atlas Population Mode是Dynamic或者Character Set里包含了你要顯示的字符。然后檢查字符集文件是不是UTF-8編碼可以用文本編輯器打開(kāi)確認(rèn)。最后檢查場(chǎng)景里TextMeshPro組件的Font Asset是否指向了正確的字體資源。如果以上都沒(méi)問(wèn)題還有一個(gè)隱蔽的原因TMP的默認(rèn)字體資源LiberationSans SDF在項(xiàng)目里被意外覆蓋了。有些教程會(huì)讓你直接修改默認(rèn)字體但這樣會(huì)影響所有使用默認(rèn)字體的TextMeshPro對(duì)象。建議的做法是創(chuàng)建獨(dú)立的Font Asset不要?jiǎng)幽J(rèn)資源。4.2 打包后中文又變回方塊編輯器里顯示正常打包后中文消失這個(gè)問(wèn)題通常和Clear Dynamic Data On Build有關(guān)。如果這個(gè)選項(xiàng)開(kāi)啟打包時(shí)會(huì)清空動(dòng)態(tài)生成的字形數(shù)據(jù)運(yùn)行時(shí)需要重新生成。但如果運(yùn)行時(shí)字體文件沒(méi)有被正確包含在包體里動(dòng)態(tài)生成就會(huì)失敗。解決方法是確認(rèn)源字體文件TTF/OTF在打包時(shí)被包含。檢查Assets/Fonts目錄下的字體文件在Inspector里確認(rèn)Include in Build選項(xiàng)是勾選的。另外如果用了Addressables或AssetBundle管理字體資源要確保字體文件和Font Asset都被正確打包。還有一個(gè)可能某些平臺(tái)比如WebGL對(duì)動(dòng)態(tài)字體生成的支持有限可能需要改用靜態(tài)圖集方案。WebGL下TMP的動(dòng)態(tài)字體生成依賴(lài)瀏覽器的字體渲染能力不同瀏覽器表現(xiàn)不一致建議在WebGL項(xiàng)目里用靜態(tài)預(yù)渲染方案。4.3 字體圖集滿(mǎn)了怎么辦動(dòng)態(tài)模式下當(dāng)圖集滿(mǎn)了且Multi Atlas Textures開(kāi)啟時(shí)TMP會(huì)自動(dòng)創(chuàng)建新圖集。但新圖集的創(chuàng)建會(huì)觸發(fā)一次內(nèi)存分配和紋理上傳可能造成卡頓。如果項(xiàng)目文本量很大頻繁觸發(fā)圖集擴(kuò)容會(huì)影響體驗(yàn)。優(yōu)化策略一是增大Atlas Resolution比如從1024x1024提升到2048x2048單張圖集能容納更多字形減少擴(kuò)容次數(shù)。二是預(yù)渲染更多常用字減少運(yùn)行時(shí)動(dòng)態(tài)生成的需求。三是監(jiān)控圖集使用情況在TMP的Font Asset Inspector里可以查看當(dāng)前圖集的填充率根據(jù)實(shí)際情況調(diào)整。我實(shí)測(cè)下來(lái)1024x1024的圖集在預(yù)渲染500常用字后還能容納大約2000-3000個(gè)動(dòng)態(tài)生成的字形對(duì)于中等文本量的項(xiàng)目足夠用了。如果項(xiàng)目有大量隨機(jī)生成的文本比如程序化生成的對(duì)話(huà)建議把Atlas Resolution提到2048x2048。4.4 常見(jiàn)問(wèn)題速查表問(wèn)題現(xiàn)象可能原因解決方法中文顯示為方塊Font Asset無(wú)中文字形設(shè)置Dynamic模式或添加字符集中文顯示為空白字符集文件編碼錯(cuò)誤確認(rèn)文件為UTF-8編碼打包后中文消失源字體未包含在包體勾選Include in Build小字號(hào)下筆畫(huà)粘連Sampling Point Size太小提高到64或72圖集頻繁擴(kuò)容卡頓Atlas Resolution太小提高到2048x2048Fallback不生效Fallback順序錯(cuò)誤調(diào)整列表順序常用字體放前面編輯器正常打包異常Clear Dynamic Data On Build根據(jù)平臺(tái)決定是否開(kāi)啟5. 性能優(yōu)化與進(jìn)階技巧5.1 字體圖集的內(nèi)存占用分析Font Asset的內(nèi)存占用主要來(lái)自圖集紋理。一張1024x1024的RGBA32紋理占4MB顯存如果用了Alpha8格式則只占1MB。TMP默認(rèn)使用Alpha8格式存儲(chǔ)SDF數(shù)據(jù)所以1024x1024圖集約1MB2048x2048約4MB。對(duì)于移動(dòng)端項(xiàng)目建議把圖集控制在2048x2048以?xún)?nèi)總顯存占用不超過(guò)8MB。如果項(xiàng)目對(duì)包體和內(nèi)存極其敏感可以考慮用TMP的Font Asset Creator工具手動(dòng)生成精簡(jiǎn)的靜態(tài)圖集只包含項(xiàng)目實(shí)際用到的字符。這樣圖集可以精確控制到最小但失去了動(dòng)態(tài)擴(kuò)展能力。適合文本固定的項(xiàng)目比如純UI展示類(lèi)應(yīng)用。5.2 多語(yǔ)言項(xiàng)目的字體管理策略如果項(xiàng)目需要支持多語(yǔ)言中文、日文、韓文、英文等字體管理會(huì)變得復(fù)雜。我的建議是每種語(yǔ)言創(chuàng)建獨(dú)立的Font Asset然后通過(guò)Fallback鏈組合。比如主字體用英文字體Fallback 1用中文字體Fallback 2用日文字體。這樣切換語(yǔ)言時(shí)只需要換主字體Fallback會(huì)自動(dòng)處理字符回退。但要注意不同語(yǔ)言的字體圖集是獨(dú)立占用的如果同時(shí)加載多套字體顯存占用會(huì)疊加。優(yōu)化方法是按語(yǔ)言動(dòng)態(tài)加載和卸載Font Asset比如切換到中文時(shí)加載中文字體切到英文時(shí)卸載中文字體釋放顯存。Unity的Addressables系統(tǒng)很適合做這種動(dòng)態(tài)資源管理。5.3 動(dòng)態(tài)字體生成的性能監(jiān)控動(dòng)態(tài)字體生成的開(kāi)銷(xiāo)主要在首次顯示某個(gè)字符時(shí)。如果一幀內(nèi)突然出現(xiàn)大量新字符比如加載一大段對(duì)話(huà)可能造成明顯卡頓。監(jiān)控方法是用Unity Profiler查看TMP_UpdateManager和FontAsset.TryAddCharacters的耗時(shí)。優(yōu)化手段一是預(yù)渲染更多常用字減少運(yùn)行時(shí)生成。二是把大段文本的顯示分散到多幀比如用打字機(jī)效果逐字顯示這樣每幀只生成少量新字形。三是用TMP的SetText方法時(shí)可以提前調(diào)用FontAsset.TryAddCharacters預(yù)生成字形避免顯示時(shí)才生成。實(shí)操心得我在項(xiàng)目里做了一個(gè)簡(jiǎn)單的預(yù)生成邏輯在加載場(chǎng)景時(shí)把該場(chǎng)景可能用到的所有文本收集起來(lái)提前調(diào)用TryAddCharacters生成字形。這樣進(jìn)入場(chǎng)景后文字顯示完全無(wú)卡頓代價(jià)是加載時(shí)間略微增加但體驗(yàn)提升很明顯。5.4 字體子集化與包體控制如果項(xiàng)目對(duì)包體大小有嚴(yán)格要求字體子集化是必做的優(yōu)化。工具方面可以用fonttoolsPython庫(kù)或者pyftsubset命令行工具把TTF/OTF文件精簡(jiǎn)到只包含項(xiàng)目用到的字符。比如pyftsubset SourceHanSans.ttf --text-filecharset.txt --output-fileSubsetFont.ttf --flavorwoff2這條命令會(huì)把SourceHanSans.ttf精簡(jiǎn)到只包含charset.txt里的字符輸出為SubsetFont.ttf。實(shí)測(cè)下來(lái)完整的思源黑體16MB子集化到3500常用字后只有2.3MB壓縮率超過(guò)85%。但子集化有個(gè)前提你必須確保項(xiàng)目所有文本都在字符集范圍內(nèi)。如果后續(xù)更新加入了新字符需要重新子集化并更新字體文件。所以建議在項(xiàng)目文本基本定稿后再做子集化或者保留一個(gè)完整的Fallback字體作為兜底。6. 項(xiàng)目實(shí)戰(zhàn)中的經(jīng)驗(yàn)總結(jié)6.1 我的最終配置方案經(jīng)過(guò)幾輪調(diào)試我的項(xiàng)目最終采用的配置如下源字體思源黑體Regular Bold子集化到3500常用字加符號(hào)兩個(gè)文件合計(jì)約4.5MBFont AssetDynamic模式Atlas Resolution 1024x1024Sampling Point Size 64Padding 10Multi Atlas Textures開(kāi)啟Clear Dynamic Data On Build開(kāi)啟預(yù)渲染字符集500常用漢字 ASCII 常用標(biāo)點(diǎn)約600字符Fallback鏈英文主字體 - 中文Regular - 中文Bold - 符號(hào)字體運(yùn)行時(shí)策略場(chǎng)景加載時(shí)預(yù)生成該場(chǎng)景文本字形對(duì)話(huà)文本用打字機(jī)效果逐字顯示這套方案在移動(dòng)端實(shí)測(cè)下來(lái)UI文字顯示清晰無(wú)卡頓包體增加約5MB顯存占用約3MB完全在可接受范圍內(nèi)。6.2 幾個(gè)容易忽略的細(xì)節(jié)第一個(gè)細(xì)節(jié)是TMP的Font Asset在Inspector里有個(gè)Is Font Asset Lookup選項(xiàng)如果項(xiàng)目里Font Asset很多開(kāi)啟這個(gè)選項(xiàng)可以加速查找但會(huì)略微增加內(nèi)存。對(duì)于字體資源不多的項(xiàng)目保持默認(rèn)即可。第二個(gè)細(xì)節(jié)是TextMeshPro組件的Extra Padding選項(xiàng)。這個(gè)選項(xiàng)會(huì)在字形周?chē)~外增加留白用于處理某些字體在特定字號(hào)下的溢出問(wèn)題。中文項(xiàng)目建議開(kāi)啟但不要設(shè)太大否則文字間距會(huì)變寬。我一般設(shè)2-3像素。第三個(gè)細(xì)節(jié)是Font Style里的Bold和Italic。TMP的Bold是通過(guò)SDF數(shù)據(jù)模擬的效果不如真正的Bold字重。如果項(xiàng)目需要加粗中文建議單獨(dú)導(dǎo)入Bold字重的字體文件創(chuàng)建Font Asset而不是用TMP的模擬加粗。模擬加粗在中文上容易出現(xiàn)筆畫(huà)粘連。6.3 后續(xù)擴(kuò)展方向這套方案目前滿(mǎn)足了我的項(xiàng)目需求但還有一些可以繼續(xù)優(yōu)化的方向。比如用TMP的Font Asset變體功能為不同字號(hào)創(chuàng)建獨(dú)立的Font Asset小字號(hào)用低分辨率圖集大字號(hào)用高分辨率圖集進(jìn)一步優(yōu)化顯存?;蛘哂肨MP_Settings的全局配置統(tǒng)一管理所有TextMeshPro的默認(rèn)參數(shù)減少每個(gè)組件的重復(fù)配置。另外如果項(xiàng)目后續(xù)要支持用戶(hù)自定義字體可以考慮用TMP_FontAsset.CreateFontAsset在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建Font Asset配合文件選擇器讓用戶(hù)導(dǎo)入自己的字體文件。這個(gè)功能在工具類(lèi)應(yīng)用中比較常見(jiàn)實(shí)現(xiàn)難度不大但要注意字體文件的授權(quán)和安全問(wèn)題。我在實(shí)際項(xiàng)目里踩過(guò)的最大一個(gè)坑是早期為了省事直接用了TMP默認(rèn)的LiberationSans SDF作為主字體然后把中文字體作為Fallback。結(jié)果發(fā)現(xiàn)英文和數(shù)字的顯示效果很一般而且Fallback切換時(shí)偶爾會(huì)出現(xiàn)基線(xiàn)不對(duì)齊的問(wèn)題。后來(lái)改成用專(zhuān)門(mén)的英文字體做主字體中文字體做Fallback并且統(tǒng)一了字體的基線(xiàn)參數(shù)問(wèn)題才解決。所以字體鏈的配置一定要在項(xiàng)目早期就規(guī)劃好后期改起來(lái)牽一發(fā)而動(dòng)全身。