NGUI裏面的文字爲啥在轉到IOS系統發佈會模糊成馬賽克狀

Unity工程中的動態字體使用很方便,在一開始的工程中,爲了減小遊戲包的大小,我們使用的是Unity內置的默認Arial字體,但是在遊戲上線測試後,很多玩家反饋個別機型字體顯示不完全,主要集中在 小米1代,OPPO,金立,中興等個別機型中。剛開始以爲是NGUI的問題,經過幾天的問題排查,發現原來是Arial字體惹的禍。

Arial字體是西文字體,並不包含中文字庫,在Unity中如果使用默認的Arial字體,在程序運行過程中如果遇到字庫中沒有的字,程序就會從系統默認字庫中查找對應的文字,如果字庫中也沒有這些字,那麼就會造成字體不顯示的現象,在Android系統中Unity默認會去查找名爲DroidSansFallback的字體,這個字體是android默認的字體,但是因爲android系統的可定製性,太過自由,很多手機廠商或者第三方rom愛好者爲了追求個性化,會去修改默認字體,替換成其他的字體,android系統是根據字體的文件名稱DroidSansFallback.ttf來找這個字體的,所以修改者只用將想要使用的字體文件名稱改爲DroidSansFallback.ttf就可以在android系統中使用了。但是Unity識別字體卻不是通過字體的文件名稱來識別的,而是通過字體內部的設置來識別,如下圖: 


這個字體是win8系統默認的字體,雙擊預覽能夠看到字體名稱是Aharoni,Unity就是通過這個名稱來找默認字體的,這就導致了那些被修改了默認字體的android系統無法顯示字體,(此現象也出現在個別window xp系統中)。

問題出現的原因找到了,那麼就容易解決了,我們只要找到一個不是太大的符合自己要求的字體,放入到unity中,所有使用Arial字體的地方,都換成自己添加的動態字體即可。 


1 Font Names 默認倒入的一個字體,這個地方會顯示這個字體的真實名字,這個參數的主要作用實際上是設置替代字體用的,當程序需要某一個字體時,首先會從當前字體查找字符,如果沒有找到,會依次查找FontNames列表裏的其他字體中的字符,直到找到,或者找完爲止。例圖中中添的幾個替代字體MYingHeiGB18030C-Bold, Droid Sans, Droid Sans Fallback, LTHYSZK,第一個MYingHeiGB18030C-Bold是當前字體的名稱(可以不用填),第二個,第三個是android系統裏的字體,第四個是小米1代所使用的字體。

Incl.FontData 選項打上勾,在倒出包的時候會把該字體添加到包中,若不打勾,則不會將該字體打包,程序運行時就會從FontNames列表裏檢索需要的字體,如果沒有,字體就不會顯示。

如果你的遊戲中一直都在使用字體A,突然有天Boss說,這個字體不好看!給我換成B字體!苦逼的你該怎麼辦?一個一個改麼?其實通過上邊所說的兩個參數,把A字體的Incl.Font Data不勾選,然後將B字體的FontName 填入A的FontNames裏,而B字體的Incl.Font Data打勾,我們可以很巧妙的將字體A全部替換成B字體,同時打包的時候又保證了只有B字體。

因爲Unity的默認字體Arial是如此的不爽,所以在此建議大家不要在工程中使用Arial字體(純英文遊戲除外)。下邊貼一個寫的批量替換NGUI中的Arial字體爲指定字體的腳本,將其放入Asset /Editor文件夾下,即可在導航欄生成工具菜單:

[csharp] view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using System.Collections.Generic;  
  4. using UnityEditor;  
  5. public class FontReplese  
  6. {  
  7. //批量替換場景中的字體  
  8. [MenuItem ("Custom/Label/ChangeSceneLabel" )]  
  9. publicstatic void ChangeSceneFont ()  
  10. {  
  11. List<UILabel> labelList = NGUIEditorTools.FindAll<UILabel> ();  
  12. ChangeLabelFont ( labelList );  
  13. }  
  14.   
  15.   
  16. publicstatic void ChangeLabelFont ( List<UILabel> labelList )  
  17. {  
  18.   
  19. Font mFont = NGUIEditorTools.LoadAsset<Font> ("Assets/font/DroidSansFallback.TTF" );//注意這個地方是要替換成的字體的路徑  
  20. if ( mFont ==null )  
  21. {  
  22. Debug.LogError (" Font not found ! " );  
  23. return;  
  24. }  
  25. foreach (var label in labelList )  
  26. {  
  27. if ( label !=null && label.trueTypeFont != null && label.trueTypeFont.name == "Arial" )//這個地方的name可以改爲原來的字體的名稱  
  28. {  
  29. label.trueTypeFont = mFont;  
  30. }  
  31. }  
  32.   
  33. Debug.LogError ( labelList.Count );  
  34. }  
  35.   
  36. //改變選中的預設上邊的字體  
  37. [MenuItem ("Custom/Label/ChangeSelectionLabelFont" )]  
  38. publicstatic void ChangeSelectObjFont ()  
  39. {  
  40. GetTypeList ();  
  41. //ChangeLabelFont ( );  
  42. }  
  43.   
  44. publicstatic List<UILabel> GetTypeList ()  
  45. {  
  46. Object[] objList =Selection.GetFiltered ( typeof ( Object ), SelectionMode.DeepAssets );  
  47. //Debug.LogError (Selection.activeObject.name);  
  48. Debug.LogError ( objList.Length );  
  49. List<UILabel> tmpList = new List<UILabel> ();  
  50. foreach (var tmp in objList )  
  51. {  
  52. if ( ( tmpas GameObject ) !=null )  
  53. {  
  54. string assetstr =AssetDatabase.GetAssetPath ( tmp );  
  55. GameObject obj =PrefabUtility.InstantiatePrefab ( tmp ) as GameObject;  
  56.   
  57. List<UILabel> tmpLabel = GetTypeIncludeChildren ( obj );  
  58. if ( tmpLabel.Count >0 )  
  59. {  
  60. ChangeLabelFont ( tmpLabel );try  
  61. {  
  62. PrefabUtility.ReplacePrefab ( obj, tmp );  
  63. }  
  64. catch ( System.Exception ex )  
  65. {  
  66. Debug.LogError ( ex.ToString () + tmp.name );  
  67. }  
  68. //Debug.LogError ( AssetDatabase.RenameAsset ( assetstr, name ) );  
  69. }  
  70.   
  71. GameObject.DestroyImmediate ( obj );  
  72. }  
  73. }  
  74. AssetDatabase.SaveAssets ();  
  75. AssetDatabase.Refresh ();  
  76. return tmpList;  
  77. }  
  78.   
  79. publicstatic List<UILabel> GetTypeIncludeChildren ( Object obj )  
  80. {  
  81. GameObject tmp = objas GameObject;  
  82. if ( tmp ==null )  
  83. {  
  84. //return new List<UILabel> ();  
  85. }  
  86. List<UILabel> tmpList = new List<UILabel> ();  
  87. UILabel tmpLabel = tmp.GetComponent<UILabel> ();  
  88. if ( tmpLabel !=null )  
  89. {  
  90. tmpList.Add ( tmpLabel );  
  91. }  
  92. foreach (Transform child in tmp.transform )  
  93. {  
  94. tmpList.AddRange ( GetTypeIncludeChildren ( child.gameObject ) );  
  95. }  
  96. return tmpList;  
  97. }  
  98.   
  99. }  


本腳本僅支持替換NGUI的UILabel所使用的字體,經測試替換預設上的UILabel字體的方法在Unity4.3版本中會導致預設無法使用,但在Unity4.5.x中完美使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章