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

使用的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. 线段树【p2629】 好消息,坏消息

    顾z 你没有发现两个字里的blog都不一样嘛 qwq 题目描述-->p2629 好消息,坏消息 历程 刚开始看到这个题,发现是需要维护区间和,满心欢喜敲了一通线段树,简单debug之后交上去 \ ...

  2. SQL语句原理与高效SQL语句(转)

    做软件开发的programers,大部分都离不开跟数据库打交道,特别是erp开发的,跟数据库打交道更是频繁,存储过程动不动就是上千行,如果数据量大,人员流动大,那么还能保证下一段时间系统还能流畅的运行 ...

  3. 【MySQL】undo,redo,2PC,恢复思维导图

    http://blog.itpub.net/22664653/viewspace-2131353/

  4. JAVA实现网页快照,存为图片格式

    原文:http://blog.csdn.net/java2000_net/article/details/3643528 截取的google的效果,将就吧,不是特别好. 但是作为普通的应用,我想这个效 ...

  5. 单元测试方法属性(Unit Test Method Attribute)

    Additional test attributes(可以在测试方法上使用的属性)As you have seen, the unit-testing subsystem within Visual ...

  6. django模板解析 循环列表中 切片和求长度

    {% for subrow in subdic.content|slice:":5" %} {% endfor %} {% if "{{subdic.content|le ...

  7. 面试题:Add Two Numbers(模拟单链表)

    题干: You are given two non-empty linked lists representing two non-negative integers. The digits are ...

  8. jstl标签设置通用web项目根路径

    在做项目时(如SSH或SpringMVC),通常需要在很多页面(jsp中的form提交)或者js代码(一般Ajax提交)中用到当前web应用的根路径(拼成访问资源如action/controller. ...

  9. DatagramPacket,DatagramSocket

    package test; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSo ...

  10. Java源码阅读Vector

    1类签名与注释 public class Vector<E> extends AbstractList<E> implements List<E>, RandomA ...