AutoCAD 3DMAX C語言 Pro/E UG JAVA編程 PHP編程 Maya動畫 Matlab應用 Android
Photoshop Word Excel flash VB編程 VC編程 Coreldraw SolidWorks A Designer Unity3D
 部落冲突安卓版下载 > Unity3D

Unity動態字體文字破碎的解決方法(Dynamic Font Broken)

部落冲突安卓版下载 2014-05-24 //www.fkutc.icu

使用Unity的動態字體繪制文字的時候,打開兩個ui界面的時候,后面的文字會顯示破碎(完全亂掉)。我使用的ui插件是Daikon Forge,由于其label的更新機制問題,最終表現的結果可能比一個文本顯示破碎更加糟糕。很可能文本控件會不停的刷新,要打開的新界面也顯示不出來。

這個從根本上說,是由于Unity的Dynamic Font實現的不夠智能。理論上NGUI也會有這樣的問題。只要你使用的是動態字體,并且渲染的文字構多。

NGUI和Daikon Forge內部在繪制文字的時候使用了Unity 的Font,這個就是動態字體。通過RequestCharactersInTexture函數向Font請求更新文字信息,然后使用GetCharacterInfo獲取文字信息來渲染。在調用GetCharacterInfo的時候要保證所有文字都通過RequestCharactersInTexture請求過了。

如果請求的時候,Font內部維護的texture不夠用了,就會觸發textureRebuildCallback的回調,通知外部使用Font的對象,其內部的texture被更新了,外部應該重新刷新。

Unity的Font默認的texture大小是256x256,在純英文字體的情況下,是完全夠用了。但是漢字、日文等東方字體就完全不夠了。而之前說的那兩個插件的使用方式都是繪制文字的時候請求一段,如果unity的刷新回調觸發,則重新刷新所有的文本控件。這樣就非常容易出現字體破碎的情況。因為一般情況下我們一次請求的文字不會很多,使用的texture不會超過256x256,unity不會自動擴展texture大小。而我們在回調函數中重新刷新字體的時候,又很容易出現texture不夠的情況,這樣就觸發了另一次刷新回調。于是就會發文本控件顯示破碎而且不停刷新的情況。

直到了問題的起因,解決方法也就出來了。只要我們請求的文字足夠多,那么unity就會內部自動擴展texture大小,于是就可以避免不停刷新的情況。我準備了2000個漢字的文本,在請求文字信息后,內部texture被擴展成1024x1024大小,這樣游戲過程中就基本夠用了。如果哪天發現這樣也不夠的話,再多準備一些漢字,把texture擴展成2048x1024就ok了。

1
2
3
4
5
6
7
8
9
10
11
12
13
static string chineseTxt = null;
public UnityEngine.Font baseFont;
public void FixBrokenWord()
{
if (chineseTxt == null) {
TextAsset txt = Resources.Load("config/chinese") as TextAsset;
chineseTxt = txt.ToString();
}
 
baseFont.RequestCharactersInTexture(chineseTxt);
Texture texture = baseFont.material.mainTexture; // Font的內部紋理
Debug.Log(string.Format("texture:{0} {1}", texture.width, texture.height); // 紋理大小
}

其中baseFont就是NGUI或者是Daikon Forge的文本渲染控件中使用的UnityEngine.Font,在初始化baseFont的時候調用一下FixBrokenWord函數就可以了 (只需要調用一次)。它會讀取一個含有常用漢字表的文本(隨意從網上的常用字表用copy一下就可以了),然后請求一下這段文本的信息,然后內部紋理就會 自動被擴展。

NGUI】移動設備上使用動態字體Label顯示不正確

方法1:

升級Unity到4.3版本以上

方法2:

首先,需要一個文本,這個文本就是你項目的字典(如果沒有,自己研究下)

之后,在游戲啟動的時候實現以下步驟:

1、載入字典txt,所有的文字放到一個string里面(暫且叫做languageString)

(3.0以前版本)

2、通過全局配置或者其他任何方式,找到你的UIFont變量font(可以在任意的label上直接取得)

3、調用font.dynamicFont.RequestCharactersInTexture(languageString, font.dynamicFontSize, font.dynamicFontStyle)

(3.0(含)以后版本)

2、通過全局配置或者其他任何方式,找到你的動態字體Font變量font

3、調用NGUIText.RequestCharactersInTexture(font, languageString)

應該就可以了。

問題的根本原因不是很了解,但是我想問題應該出現在動態字體創建的texture大小上。

一般問題是出現在切換界面的時候,所以應該是這個時候,如果texture大小不夠用,重新調整了texture,導致之前的texture的uv對應不上。

通過上面的方法,在游戲最開始就會創建一個2048*1024大小的texture(我用的是3000多個常用漢字只有不到2M,因為是純色的圖)

所以不會浪費太多內存,也比使用bitmap子圖省。

提供一個3.0.7的腳本。之前版本的自己看著改吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using UnityEngine;
using System.Collections;
 
 
/// <summary>
/// SZUI dynamic font problem fix.
/// Usage : attach this to a gameobject or use SZUIDynamicFontProblemFix.DynamicFontProblemFix
/// </summary>
public class SZUIDynamicFontProblemFix : MonoBehaviour {
 
/// <summary>
/// The font. your ttf
/// </summary>
public Font font;
 
/// <summary>
/// The text. your language file
/// </summary>
public TextAsset text;
 
private static bool isFixed = false;
 
private static SZUIDynamicFontProblemFix inst;
private static SZUIDynamicFontProblemFix Inst
{
get
{
if (inst == null)
{
GameObject go = new GameObject(typeof(SZUIDynamicFontProblemFix).Name);
inst = go.AddComponent<SZUIDynamicFontProblemFix>();
}
return inst;
}
}
 
void Awake()
{
if (inst == null)
{
inst = this;
}
if (inst != null && inst != this)
{
Destroy(this.gameObject);
return;
}
DynamicFontProblemFix();
}
 
public static void DynamicFontProblemFix()
{
if (!isFixed)
{
isFixed = true;
NGUIText.RequestCharactersInTexture(Inst.font, Inst.text.text);
}
}
}

原文鏈接:

//blog.csdn.net/langresser_king/article/details/22095235

//blog.csdn.net/u012091672/article/details/17414811


建議使用電驢(eMule)下載分享的資源。

說明
:本教程來源互聯網或網友分享或出版商宣傳分享,僅為學習研究或媒體推廣,www.fkutc.icu不保證資料的完整性。
 
上一篇:【Unity C#編程】自定義編輯器(一)  下一篇:Unity將光線追蹤技術應用到實時互動游戲