关于 UGUI 字体花屏或乱码。
我们项目从某个时候开始ui突然开始出现字体花屏现象(unity 开发版本:5.3.6p6),而且很难必现却又时有发生,确实查找和解决起来并不太容易。
关于这个问题,uwa官方给出了解释,http://blog.uwa4d.com/archives/techsharing_35.html, http://blog.uwa4d.com/search/%E5%AD%97%E4%BD%93/。可用的方案就是一开始把字体扩容到足够大,但对于常用汉字就有3000多个,再加上不同的大小和样式,不同的字体,内存占用光想一想就很可观,所以将此当做最保底的方案。Unity 官方应该是解决过这个问题,但是没有彻底。但是我更加高度怀疑的是:FontTexture 本身的生成和对应的 UV 信息并没有问题,而是字体使用的 UV 有问题(没有更新),uwa 提供的方案可能是针对的早期问题,也许现在问题是新引起的。
后来又看到雨松MOMO的博客也有提到并给出了解决方案:http://www.xuanyusong.com/archives/4259,这个方法很好,在 FontTexture 重建时在其后的 LateUpdate 中刷新所有的 Text,这个方案也是我希望的方式,不会产生过多的浪费字体纹理。不过 GameObject.FindObjectsOfType<Text>() 这个调用我觉得对于 Text 过多的场景恐怕效率堪忧,翻阅了下 UI 的源码,发现其中有个类 UnityEngine.UI.FontUpdateTracker 就是专门用来更新 Text 相关字体信息的,但是接口都不是 public,但是可以反射调用就好,所以可以用此对 雨松MONO 的方案优化一下:
using UnityEngine;
using System.Collections;
using System.Collections.Generic; public class DynamicFontTextureRebuildTracker : MonoBehaviour
{
private class FontUpdateNode
{
private bool m_FontTextureRebuilt = false;
private Font m_FontRebuilt = null; public FontUpdateNode(Font font)
{
m_FontRebuilt = font;
Validate();
} public void Validate()
{
if (null == m_FontRebuilt)
{
m_FontTextureRebuilt = false; Debug.LogWarning("You need a actual font to validate!");
return;
} m_FontTextureRebuilt = true;
} public void Invalidate()
{
m_FontTextureRebuilt = false;
} public bool NeedUpdate
{
get { return m_FontTextureRebuilt && (null != m_FontRebuilt); }
} public Font font
{
get { return m_FontRebuilt; }
}
} private System.Reflection.MethodInfo m_RebuildForFont = null;
private List<FontUpdateNode> m_FontUpdateList = new List<FontUpdateNode>(); private static DynamicFontTextureRebuildTracker m_Instance = null; void Awake()
{
if (null != m_Instance)
{
Debug.LogError("There is only one DynamicFontTextureRebuildTracker instance allowed!");
Destroy(gameObject);
return;
} m_Instance = this;
} // Use this for initialization
void Start()
{
Font.textureRebuilt += OnFontTextureRebuilt; System.Type fontUpdateTrackerType = typeof(UnityEngine.UI.FontUpdateTracker);
m_RebuildForFont = fontUpdateTrackerType.GetMethod("RebuildForFont", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
Debug.Log("Get RebuildForFont method is: " + m_RebuildForFont);
} // Update is called once per frame
void LateUpdate()
{
if (null == m_RebuildForFont)
{
return;
} for (int i = ; i < m_FontUpdateList.Count; i++)
{
FontUpdateNode node = m_FontUpdateList[i];
if (node.NeedUpdate)
{
Font font = node.font;
m_RebuildForFont.Invoke(null, new object[] { font }); // Log rebuild.
Texture fontTexture = font.material.mainTexture;
Debug.Log(string.Format("Texture of dynamic font \"{0}\" is enlarged to {1}x{2}.", font.name, fontTexture.width, fontTexture.height)); node.Invalidate();
}
}
} void OnDestroy()
{
Font.textureRebuilt -= OnFontTextureRebuilt;
} private void OnFontTextureRebuilt(Font font)
{
bool findThisFont = false;
for (int i = ; i < m_FontUpdateList.Count; i++)
{
FontUpdateNode node = m_FontUpdateList[i];
if (node.font == font)
{
node.Validate();
findThisFont = true;
break;
}
} if (!findThisFont)
{
m_FontUpdateList.Add(new FontUpdateNode(font));
}
} //void OnGUI()
//{
// if (GUI.Button(new Rect(30.0f, 50.0f, 200.0f, 50.0f), "Force Update Text"))
// {
// for (int i = 0; i < m_FontUpdateList.Count; i++)
// {
// Font font = m_FontUpdateList[i].font;
// m_RebuildForFont.Invoke(null, new object[] { font });
// Debug.Log(string.Format("Force rebuild text for font \"{0}\".", font.name));
// } // Debug.Log("Force rebuild all text ok!");
// }
//}
}
为了验证确实是 FontTexture 是 ok 的而乱码只是 Text 的 uv 不正确,可以将 OnGUI 的代码放开,将 LateUpdate 的代码注释,然后运行游戏,在出现字体乱码后点击 “Force Update Text” 按钮,如果文字乱码立即消失,就证实了上面的猜测仅仅是 Text UV 没有更新而已。经过在手机上实际测试出现乱码后立即点击按钮,文字均显示正常,也证实了这个问题。
使用时在初始场景中新建一个空 GameObject,然后 DontDestroyOnLoad,再挂上 DynamicFontTextureRebuildTracker 脚本即可。后来游戏中(ios, android)就再也没有出现过字体花屏乱码等现象。
最后附上该脚本下载地址:http://pan.baidu.com/s/1c1LPoJY
2017-07-01 更新:
最近我们项目的 Unity 版本一直稳定在 5.3.7p4,但是极少数情况下(甚至是某一小段时间内)依然偶尔出现了字体花屏,但是最近又没有了,不知道原因,有可能其它系统引起了问题。
2017-07-06 更新:
最近测试同学报告说,最近偶尔依然出现的字体花屏不像以前一进场景就花掉,而是出现了角色单位后就变化了,进一步缩小了范围,先记录下,后面有时间研究下。
关于 UGUI 字体花屏或乱码。的更多相关文章
- udp 视频包网络传输花屏
视频数据传输在传输层可以选择TCP或者UDP,TCP面向连接,传输中断,发送端是知道的.TCP传输的好处是不丢包,坏处是网络不太好的情况下会越堵越严重.UDP非面向连接,发送端只管发送数据,接收端有没 ...
- 安装ubuntu12.04LTS卡住以及花屏问题
昨天在XP下用grub4dos安装了ubuntu12.04LTS,总体上还算比较顺利,中途有碰到两个异常问题,解决了记录一下. 问题一:安装过程中读取ISO镜像文件时,卡在"checking ...
- android 控件花屏问题
发现自己的手机上某个界面出现了花屏,某些控件背景被拉伸过多遮住了其他控件,很难看.这种现象高概率出现,分析了下发现:一旦发生这种现象,必然 会打印下面这种log,google了下,这种log应该是硬件 ...
- 宝爷Debug小记——Cocos2d-x(3.13之前的版本)底层BUG导致Spine渲染花屏
最近在工作中碰到不少棘手的BUG,其中的一个是Spine骨骼的渲染花屏,在战斗中派发出大量士兵之后有概率出现花屏闪烁(如下图所示),这种莫名奇妙且难以重现的BUG最为蛋疼. 前段时间为了提高Spi ...
- opencv imwrite保存图片花屏的问题
问题:在项目中用opencv的imwrite保存图片出现花屏的问题,如下图: 思路:1. 因为项目中的图像数据(float类型,0-255)是在GPU中,保存的话:可以用CPU保存图片,也可以用GP ...
- Windows 花屏问题
已经有2台电脑 Windows 10 系统出现花屏现象,表现为比较炫的界面出现花屏.文字显示不全.移位.闪烁等,如果点击“设置”.“开始”,Chrome浏览器等:比较平素的界面显示正常,比如资源管理器 ...
- 关于笔记本安装parrot和kali的一些问题(花屏,息屏,屏幕不能休眠)
新入手了个笔记本,还是想跟原来一样装回熟悉的kali环境中,结果我的天啊,这一路坑,简直了. 写下我遇到的问题吧,算是给大家提供一些解决方法. 1.安装kali和parrot出现无法引导的grub的情 ...
- recovery 升级界面顶部花屏问题分析
说明: 实际解决问题的过程有点曲折,后面找到原因,分析清楚问题后,总结下正确的分析方法,大致分析流程如下. 问题描述: 在进入recovery的时候,第一次上电进入recovery时,顶部会有一长条花 ...
- LCD显示异常分析——开机闪现花屏【转】
转自LCD显示异常分析--开机闪现花屏 最近在工作中,有同事遇到LCD开机瞬间会闪现雪花屏的问题,而这类问题都有个共同点,那就是都发生在带GRAM的屏上,同样的问题,在休眠唤醒时也会出现. 其实这类问 ...
随机推荐
- PHP常见算法-面试篇(2)
1.顺序查找 思路分析: 从数组的第一个元素开始一个一个向下查找,如果有和目标一致的元素,查找成功:如果到最后一个元素仍没有目标元素,则查找失败. 代码实现: <?php function se ...
- 使用Github总结
1. 使用Git GUI 首先熟悉一下GUI,如下: 第一步,首先将代码fork到自己的版本库下面,如下: 并获取clone URL,如下图: 然后点击GUI克隆已有版本库,如下图: 点击克隆就可以得 ...
- linux sed命令学习
. Sed简介 . 定址 . Sed命令 . 选项 . 元字符集 . 实例 . 脚本 . 小技巧 . Sed简介 sed是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中, ...
- 【JTA】JTA允许应用程序执行分布式事务处理
JTA,即Java Transaction API,JTA允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据.JDBC驱动程序的JTA支持极大地增强了数据访问能力. htt ...
- 破坏之王——ddos攻击与防范 读书笔记
好久没写博客了,最近把绿盟的<破坏之王——ddos攻击与防范>又翻了一下,整理了关于DDOS分类和原理的xmind图~~ 百度云盘:http://pan.baidu.com/s/1i3ms ...
- LCA——倍增求解
LCA,即最近公共祖先,用于解决树上两点的最近公共祖先问题. ; lca(1,2)=3;(原谅我的绘画水平) LCA的求解有三种算法(我知道的)——tarjan,倍增,线段树(我只会两种),NOIp之 ...
- 重置mysql密码
如何修改mysql root密码 忘记MySQL ROOT密码是在MySQ使用中很常见的问题,可是有很多朋友并不会重置ROOT密码,那叫苦啊,特写此文章与大家交流: 1.编辑MySQL的配置文件:my ...
- android开发之---文字居中---android中去掉标题栏
1. 让textView里面的内容水平居中 : android:gravity="center_horizontal" 2. 让textView控件在它的父布局里水平居中 ...
- 从某一日期开始过day天的日期
一个SX问我的,我就写了写......从2010.1.1开始,给了一组测试数据3的话输出2010.1.4星期1,所以说2010.1.1是星期五,总星期就是 (day+5)%7==0?7:(day+5) ...
- Android:一个高效的UI才是一个拉风的UI(一)
开篇 Android是一个运行在移动终端上的操作系统,跟传统PC最大的不同所在就是移动终端的资源紧缺问题“比较”明显,当然对于一些屌丝机型,应该用“非常“来形容才靠谱.所以经常会出现在一些比较缺乏青春 ...