• NGUI插件文字消失或破碎的问题


    Unity动态字体文字破碎的解决方法(Dynamic Font Broken)

    使用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); 
            
        
    }

    原文链接:

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

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

  • 相关阅读:
    MySql常用数据操作
    使用requests+BeaBeautiful Soup爬取妹子图图片
    抓取猫眼电影排行
    Exec执行拼接字符串时遇到的问题及Sql执行函数时需要注意的事项
    c#小知识点
    MVVM 与 sql
    Dictionary
    sql表信息查询
    XAML特殊字符
    编程细节
  • 原文地址:https://www.cnblogs.com/harlan1009/p/4671065.html
Copyright © 2020-2023  润新知