前往
大廳
主題

【踩坑筆記#1】在WebGL平台,為什麼有些裝置的字體顯示不出來?

黃葉 | 2025-04-04 17:34:43 | 巴幣 1002 | 人氣 60

今天來聊聊昨天踩的坑,並且整理一篇讓我未來不要忘記的(ˋ.ω.)b
 
昨天在Threads日更中提到「手機端的文字顯示不出來」
這裡就得先提到Unity的文字樣式是怎麼運作的了
▲ 正常來說應該要顯示「開始遊戲」


 
我所使用的是TextMesh Pro(TMP)作為UI組件,利用它可以選定文字樣式與文字表輸出一個Asset;而套用了這個Asset的所有TMP物件,都可以經由調整唯一的Asset設定來做到調整全部使用這個Asset的UI物件。
 
這個做法可以解決Unity預設的字型不支援中文的問題,同時也大幅的讓調整UI風格的工作成本降低了。
聽起來很方便對吧?
那麼怎麼會出現兩個不同裝置結果不一的情況呢?
 
這個時候就得提到TMP是怎麼將字表轉成可用的文字的了
實際上,我們所輸入的字表會被轉成圖形紋理,這可以粗略的理解成「輸入的文字被轉成圖片了」;而在創建字型Asset時,Atlas Resolution選項則是這整張圖片的解析度。
而既然是整個字表共用這一個解析度,那麼若字表內的字數很多時,每個字被分配到的可用空間就會很小,進而產生字變的很模糊等無法正常顯示,或者有部分字無法被包含進Asset內的問題。
既然這是圖形解析度,想當然的是,當這個Asset所使用解析度相對大時,就會使得在開啟遊戲是會需要用到更多的資源來讀取這個部分,也因而可能產生所需的效能相對較高的情況。
說到這裡,答案也就呼之欲出了。
 

 
那麼所以說為什麼會產生手機端無法正常顯示文字格式,而電腦端就可以的情況呢?
簡單來說:「裝置支援的Atlas Resolution低於我們打包在遊戲包體裡的參數值」,導致了我們在啟動遊戲時,處理這方面的程序就會將原本應該正常顯示的「字」回彈成預設的Dummy Texture(虛擬紋理),也就是上述問題中看到的方框。
 
解決辦法:針對裝置降低所使用字型Asset的Atlas Resolution
這個做法是最簡單直接的,只要重新輸出一個裝置可支援解析度的新Asset就可以了。
手機運行時,我的網頁Console產生了這個錯誤訊息;
這代表我所使用的8192x8192解析度過大,必須調降到4096x4096以下才可被支援

當然這個做法有幾個缺點:
★缺點1:
如果真實使用到的字庫很大時,在降低參數時很有可能會因為可用的解析度(圖形大小)不夠,導致無法容納字表內的所有字。
這裡我使用了他人提供的中文字表,使得字數特別多
★缺點2:
每個裝置可支援的解析度不盡相同,在我的手機的場合是4096x4096以下,但如果裝置更為低階,那麼這個問題就可能不被完全解決。
 
另外,值得注意的是,這裡提到的「裝置」與其可支援的解析度是根據平台所支援的為主;以我的情況來說,8192x8192的解析度在我使用APK直接安裝遊戲程式到手機上時是可以正常執行的,而當「以WebGL放到itch.io並使用手機執行」才產生了上述的問題。
 
★上述缺點的解決辦法:
缺點1中提到,當字表的字數大於Atlas Resolution的可容許值的話,會有缺字的問題產生。
那麼有沒有辦法針對我想要用到的字做紋理生成,並且讓我們所設定的解析度值可以保持在足夠低的情況呢?
有的兄弟,有的。
這種時候,我們可以啟用動態的紋理生成功能,來讓系統在先讀取到字之後才從字表中生成對應的字體紋理。

步驟1. 我們先將字型的解析度調低到可接受的值,輸出Asset
步驟2. 從Project找到該Font Asset
步驟3. 從Inspector將Multi Altas Texture打開
 
這個時候就可以看到字體出現了,而我們上述步驟所做的,正是先限制了字型Asset的解析度大小,並且使其只在使用到該字時才將對應的字型生成對應的紋理;而MultiAltas Texture的功能則是確保使用的字數所需的解析度超出了我們Atlas Resolution的設定值時,可以額外生成多張「圖紙」來滿足更多字的需求。
上述步驟完成後,就可以看到文字在編輯器內顯示了
 
但同樣的,動態生成的辦法的缺點是可能在文字出現的第一刻會有一定的延遲,整體還得要評估延遲的情況做出決定。
下下策就是依然使用靜態的生成辦法,但儘可能減少字庫的字數,或者創建多的低解析度的Asset。
 

 
字體問題成功解決 (ˋ.ω.)b

文章的最後打支預防針(?
我是一個遊戲開發新手,上述的內容可能不完全正確
如果看到這的你注意到了我有說錯或描述不好的部分,歡迎留言補充或指正!

追蹤 創作集

作者相關創作

相關創作

更多創作