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

使用的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. Tarjan缩点【p1726】上白泽慧音

    Description 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的 ...

  2. SQL PARTITION BY:列值改变时重置计数

    现有数据如下: 需求:以科目为单位 对分数进行排序 SELECT *, ROW_NUMBER() OVER (PARTITION BY 科目 ORDER BY 分数 DESC) AS NUM FROM ...

  3. sql server 性能调优 资源等待之网络I/O

    原文:sql server 性能调优 资源等待之网络I/O 一.概述 与网络I/O相关的等待的主要是ASYNC_NETWORK_IO,是指当sql server返回数据结果集给客户端的时候,会先将结果 ...

  4. C++ development cross platforms

    1. target platforms: linux suse, windows server, both use vmware virtual machine on lab server. 2. c ...

  5. 【GitHub】README.md文件中 markdown语法 插入超链接

    语法: [Spring-data-jpa 查询 复杂查询陆续完善中](http://www.cnblogs.com/sxdcgaq8080/p/7894828.html) [文本](URL) 效果:

  6. mapx 32位在win8 64位上使用

    在可以安装32位mapx的电脑上安装并破解后,将安装文件复制出来,放到c盘根目录下,用下面语句进行注册即可 Regsvr32 C:\MapX\Mapx50.DLL Regsvr32 C:\\MapX\ ...

  7. Ubuntu16.04 -- 后台进程Nohup

    nohup用于使程序在用户退出登陆.关闭终端之后仍能继续运行 用法: nohup your_command & #(符号&使程序在后台运行) exit #(退出nohup模式) 启动后 ...

  8. C#日期格式化,时间

    日期转化一 为了达到不同的显示效果有时,我们需要对时间进行转化,默认格式为:2007-01-03 14:33:34 ,要转化为其他格式,要用到DateTime.ToString的方法(String, ...

  9. codeigniter与swfupload完整解决方案

    转自:http://blog.sina.com.cn/s/blog_6d8dc8eb0100s4bv.html codeigniter(简称ci)有研究了一段时间了,看重的是ci的轻量,便捷,最近公司 ...

  10. Python中的*args和**kwargs的理解与用法

    一.简述 1.*args和**kwargs 这两个是python中方法的可变参数. 2.*args表示任何多个无名参数,它是一个tuple: 3.**kwargs表示关键字参数,它是一个dict.并且 ...