在我们游戏的开发过程中,在部分手机上运行游戏的时候,出现了字体丢失的问题,出问题的手机似乎用的都是高通芯片。

使用的unity是4.2.0版本,ngui是3.4.9版本。

在unity的论坛及unity answer中寻找问题的原因及解决办法许久未果,后来在csdn里偶然找到一篇博文,里面讲到的问题出现的原因以及相应的解决办法。根据文中的办法,我试验后证实的确可以解决问题。

博文地址:http://blog.csdn.net/langresser_king/article/details/22095235

在unity editor中可以看到,使用的字体ttf文件下,会生成一个texture文件及material文件。当需要显示文字的时候,会通过RequestCharactersInTexture函数向Font请求更新文字信息,然后使用GetCharacterInfo获取文字信息来渲 染。在调用GetCharacterInfo的时候要保证所有文字都通过RequestCharactersInTexture请求过了。

如果请求的时候,Font内部维护的texture不够用了,就会触发textureRebuildCallback的回调,通知外部使用Font的对象,其内部的texture被更新了,外部应该重新刷新。

原文中提到,是因为texture的大小没有被及时扩大而导致字体丢失。但是在我多次测试之后,猜测问题的原因应该不是这一点。因为在PC上或者其他手机上并不会出现字体丢失的问题,问题并不是出现在unity动态字体的策略上。但是这个问题是可以通过在最开始的时候使用方法将texture尺寸扩大的做法来规避掉。真正的原因实在未能找出。

下面提供规避掉这个问题的做法,供参考:

private void FixBrokenWord()
{
if (chineseText == null)
{
var wordFileRes = ResMngr.GetInstance().LoadSync("ui", "UI/font/chineseWords");
if (wordFileRes != null)
{
TextAsset worldFile = wordFileRes.GetObject() as TextAsset;
chineseText = worldFile.text;
Debug.Log(string.Format("chinese font size: {0}", chineseText.Length));
}
}
var fontRes = ResMngr.GetInstance().LoadSync("ui", "UI/font/font_FZCYJW_28");
if (fontRes != null)
{
GameObject fontPrefab = fontRes.GetObject() as GameObject;
baseFont = fontPrefab.GetComponent<UIFont>().dynamicFont;
}
if (baseFont != null)
{
baseFont.RequestCharactersInTexture(chineseText, 28);
Texture texture = baseFont.material.mainTexture;
Debug.Log(string.Format("Texture size: {0}, {1}", texture.width, texture.height));
}
fontRes = ResMngr.GetInstance().LoadSync("ui", "UI/font/font_STXINGKA_54");
if (fontRes != null)
{
GameObject fontPrefab = fontRes.GetObject() as GameObject;
baseFont = fontPrefab.GetComponent<UIFont>().dynamicFont;
}
if (baseFont != null)
{
baseFont.RequestCharactersInTexture(chineseText, 54);
Texture texture = baseFont.material.mainTexture;
Debug.Log(string.Format("Texture size: {0}, {1}", texture.width, texture.height));
}
}

这个可以在游戏开始的时候调用一次,通过RequestCharactersInTexture函数,传入一个较大的字符串来使得unity扩大texture的大小。

另外如果游戏里所使用到的文字都是通过配置表来加入的,附送一个函数,来统计游戏中所有用到的文字,并生成上一函数需要的文字文本文件。

[MenuItem("Custom/Statistic Words")]
public static void StatisticWords()
{
//用于统计字符
Dictionary<char, int> wordMap = new Dictionary<char, int>();
string[] txtFiles = Directory.GetFiles("Assets/Resources/Data/", "*.txt");
for (int i = 0; i < txtFiles.Length; ++i)
{
Debug.Log("> open file: " + txtFiles[i]);
string textContent = File.ReadAllText(txtFiles[i], System.Text.Encoding.UTF8);
Debug.Log("> file " + txtFiles[i] + " size: " + textContent.Length);
for (int wordIndex = 0; wordIndex < textContent.Length; ++wordIndex)
{
int useCount = 0;
wordMap.TryGetValue(textContent[wordIndex], out useCount);
wordMap[textContent[wordIndex]] = useCount + 1;
}
} Dictionary<char, int> sortedWordMap = new Dictionary<char, int>();
sortedWordMap = (from entry in wordMap
orderby entry.Value descending
select entry).ToDictionary(pair => pair.Key, pair => pair.Value);
IEnumerator enumerator = sortedWordMap.Keys.GetEnumerator();
StringBuilder sBuilder = new StringBuilder(); while (enumerator.MoveNext())
{
sBuilder.Append(string.Format("{0}:\t{1}\n", enumerator.Current,
sortedWordMap[(char)enumerator.Current]));
}
File.WriteAllText("Assets/Resources/UI/Font/sortedChineseWords.txt",
sBuilder.ToString(), Encoding.UTF8);
sBuilder = new StringBuilder();
enumerator = sortedWordMap.Keys.GetEnumerator();
int wordCount = 0;
while (enumerator.MoveNext()&&wordCount<800)
{
wordCount++;
sBuilder.Append(enumerator.Current);
}
Debug.Log("> Total word: " + sBuilder.ToString().Length);
File.WriteAllText("Assets/Resources/UI/Font/chineseWords.txt", sBuilder.ToString(),
Encoding.UTF8);
}

如果有知道unity这个丢失字体真正原因的,欢迎告知。

ps: 上文中从Resources目录里取得文本文件及font文件,用的是我们自己实现的ResMngr,可自行更换成unity原来的方法

Unity动态字体在手机上出现字体丢失问题解决的更多相关文章

  1. fontforge制作自定义字体及在手机上应用举例——张鑫旭

    一.看似无关紧要的事件背景 之所以花时间折腾fontforge这个软件,去制作什么自定义的字体是有原因滴. 之前提过,最近我抽空将公司的手机软件HTML5网页化.期间碰到这么一个问题,页面低栏上的电话 ...

  2. Dynamic CRM 2013学习笔记(二十六)报表设计:Reporting Service报表 动态参数、参数多选全选、动态列、动态显示行字体颜色

    上次介绍过CRM里开始报表的一些注意事项:Dynamic CRM 2013学习笔记(十五)报表入门.开发工具及注意事项,本文继续介绍报表里的一些动态效果:动态显示参数,参数是从数据库里查询出来的:参数 ...

  3. UNITY 优化之带Animator的Go.SetActive耗时问题,在手机上,这个问题似乎并不存在,因为优化了后手机上运行帧率并未明显提升

    UNITY 优化之带Animator的Go.SetActive耗时问题,在手机上,这个问题似乎并不存在,因为优化了后手机上运行帧率并未明显提升 经确认,这个问题在手机上依然存在,不过占的比例非常小.因 ...

  4. 便捷的方式在手机上查看Unity3D的Console Log(调试信息)

    Logs Viewer 功能描述 Using this tool you can easily check your editor console logs inside the game itsel ...

  5. 便捷的方式在手机上查看Unity3D的Console Log(调试信息 日志)

    Logs Viewer 功能描述 Using this tool you can easily check your editor console logs inside the game itsel ...

  6. CSS在线字体库,外部字体的引用方法

    目录: 1:CSS家族五大字体 2:360和谷歌外部字体引用方法 3:谷歌外部字体引用方法详解 4:@font-face用法详解 一: {font-family:serif,sans-serif,fa ...

  7. CSS在线字体库,外部字体的引用方法@font-face

    @font-face是CSS3中的一个模块,他主要是把自己定义的Web字体嵌入到你的网页中,随着@font-face模块的出现,我们在Web的开发中使用字体不怕只能使用Web安全字体,你们当中或许有许 ...

  8. h5 audio标签在手机上不能自动播放????

    最近在做一个微信端的项目,快到接近尾声的时候,发现还没放入音频,于是乎,放入音频,在电脑端测试一切正常,无阻碍. 后来在手机上测试,发现背景音乐不能播放,于是开始找错,刚开始以为是IIS服务器出错,结 ...

  9. [Unity][Heap sort]用Unity动态演示堆排序的过程(How Heap Sort Works)

    [Unity][Heap sort]用Unity动态演示堆排序的过程 How Heap Sort Works 最近做了一个用Unity3D动态演示堆排序过程的程序. I've made this ap ...

随机推荐

  1. (3)Oracle提供的.net连接驱动

    老的visual studio不能用 ( .NET 4 以后才能用) Oracle Data Access Components (ODAC) 是什么? ODAC中文名称叫Oracle访问存取组件,里 ...

  2. springmvc适配器的应用

         前言     关于SpringMVC初始化ContextLoader中的XMLWebApplicationContext,以及DispatcherServlet初始化等等,这样的原理 已经有 ...

  3. Python与数据结构[1] -> 栈/Stack[1] -> 中缀表达式与后缀表达式的转换和计算

    中缀表达式与后缀表达式的转换和计算 目录 中缀表达式转换为后缀表达式 后缀表达式的计算 1 中缀表达式转换为后缀表达式 中缀表达式转换为后缀表达式的实现方式为: 依次获取中缀表达式的元素, 若元素为操 ...

  4. shell 查找目录

    查找目录:find /(查找范围) -name '查找关键字' -type d

  5. MailKit---如何知道文件夹下有多少封未读邮件

    如果在mailkit中,文件夹已经选中并打开了的话,那直接使用ImapFolder.Unread属性就可以获取到有多少封未读邮件了. 如果文件夹没有打开,那么你还可以使用查询状态的方法来获取未读状态的 ...

  6. FragmentTransaction的commit的异步操作

    FragmentTransaction是异步的,commit()仅是相当于把操作加入到FragmentManager的队列,然后FragmentManager会在某一个时刻来执行,并不是立即执行.所以 ...

  7. python3使用configparser解析配置文件

    http://www.jb51.net/article/87402.htm 需要注意的是每一个字段后面的值外面没有引号,切记,自己第一次配置时,加了引号,搞了半天 没找到错误,, 在用Python做开 ...

  8. jmap -histo pid 输出的[C [B [I [S methodKlass的含义

    转载于https://yq.aliyun.com/articles/43542 摘要: jmap -histo pid 输出结果样式  num     #instances         #byte ...

  9. java学习之输入,输出流

    输入流与输出流 1,流的分类:字节流和字符流 区别如下: 1,字节流(8位Unicode)在操作的时候本身是不会用到缓冲区(内存)的byte,是与文件本身直接操作的,而字符流(16位Unicode)在 ...

  10. Node.js模块导出exports 和 module.exports 的区别

    原文: https://blog.csdn.net/Pwiling/article/details/51958693 每一个node.js执行文件,都自动创建一个module对象,同时,module对 ...