当前位置: 首页 > news >正文

【Unity3D优化】优化多语言字体包大小

在多语言出海的手游项目中,字体资源管理是一个容易被忽视、但对性能和包体影响极大的问题。尤其是当项目需要支持中、日、韩等字符集庞大的语言时,完整字体往往动辄数十MB,不仅增加了包体体积,还在运行时造成内存浪费

本文将介绍我在一个中轻度休闲手游项目中,针对多语言字体资源做的一套精简子集方案。最终结果是——在不影响显示完整度的前提下,将原始字体包体积减少了50%~60%


一、问题背景

在国际化手游中,常见支持的语言包括:

  • 字符量少:英语、法语、德语、俄语、西班牙语等(拉丁系)

  • 字符量大:简体中文、繁体中文、日语、韩语

以Noto系列字体为例,若将所有字符打包完整支持,单个 .ttf 文件可能在 30~50MB 之间。对于中轻度手游,既不需要完整支持Unicode,又希望控制首包大小与运行时内存占用,因此我们考虑引入“子集字体”机制。


二、子集化思路概览

我们采用了如下策略:

步骤内容说明
1基础字符集筛选包含所有西方语言字符(字母、数字、常用标点)
2常用字符统计对于中、日、韩,从Wikipedia等资源收集常用字符集
3多语言文本扫描补充项目本身的多语言配置表中,提取所有实际出现的字符
4字体子集化使用 fonttools 脚本化裁剪 .ttf 字体包

通过以上方法,保证了显示完整性极限减重的兼顾。


三、语言维度的字符筛选策略

3.1 西方语言:直接全收

对于英语、法语、德语、西班牙语、俄语等拉丁或西里尔语系:

  • 字符量相对较少

  • 直接使用标准字符集(Basic Latin + Latin-1 Supplement + Cyrillic等)

包括:
- A-Z, a-z, 0-9
- 标点: !@#$%^&*()_+-=[]{}|;:'",.<>?
- 拓展拉丁与西里尔字母区间

3.2 中文、日文:基于常用字

我们查阅了Wikipedia与通用汉字集,提取如下:

  • 简体中文:约 5400 常用字

  • 繁体中文:约 7500 常用字

  • 日语:约 2136 常用汉字(常用汉字表)、另含假名(约100个)

常用字表处理脚本略,可按需要爬取或整理字典。

3.3 韩文:程序生成字符表

韩语的 Hangul 是音节组合体,Unicode中有明确的区段可直接构造:

def generate_korean():start_code = 0xAC00end_code = 0xD7A3korean_syllables = ''.join(chr(code) for code in range(start_code, end_code + 1))with open("./LanguageDatabase/KoreanCommon.txt", "w", encoding="utf-8") as file:file.write(korean_syllables)

此脚本可一次性生成 11172个 Hangul 音节,覆盖绝大多数韩文文本需要。


四、多语言文本补充字符收集

在实际游戏中,UI文本多以表格(如CSV、JSON)存储。我们通过扫描多语言配置表,提取项目内所有文本实际使用到的字符

def extract_used_characters(config_paths):all_chars = set()for path in config_paths:with open(path, 'r', encoding='utf-8') as f:content = f.read()all_chars.update(content)return ''.join(sorted(all_chars))

这样可以有效补充如“游戏术语”、“人名”、“外来语”等未出现在常用字表但实际需要的字符。


五、使用fonttools裁剪字体文件

我们选用 fonttools 库进行 .ttf 文件子集化操作。

5.1 安装依赖

pip install fonttools

5.2 字体裁剪脚本

from fontTools.subset import Subsetter, Options
from fontTools.ttLib import TTFont
from fontTools.subset import load_font, save_fontdef generate_complete_font():fontName = "XXFont"options = Options()options.drop_tables += ['DSIG']  # 删除数字签名font = load_font("./Font/" + fontName + ".ttf", options)subsetter = Subsetter(options)# 常用字集合 + 项目文本字符subsetText = generate_char_set()subsetter.populate(text=subsetText)subsetter.populate(unicodes=[0x0020, 0x000A, 0x0009, 0x200B, 0x00A0, 0x3000])  # 空格类字符补充subsetter.subset(font)save_font(font, "./Font/" + fontName + "-Sub.ttf", options)

可结合项目资源构建自动化流程,在打包阶段自动执行。


六、最终成果与效果

原字体原大小子集后大小缩减比例
NotoSansCJK.ttc42MB18MB↓约57%
CustomGameFont.ttf24MB10MB↓约58%

此外,运行时加载该字体的内存占用也相应减少,并无字符缺失问题。


七、总结与展望

通过多语言子集优化策略,我们达成了以下目标:

  • 显著减少了字体资源体积;

  • 降低了运行时内存占用;

  • 保证了文本完整显示,适配了多语言UI需求;

  • 易于扩展,后续支持新语言只需增补字符集。

该方法适用于多数Unity手游项目,特别是出海产品、UI密集型的轻度游戏。

相关文章:

  • NuGet 从入门到精进全解析
  • Transformers KV Caching 图解
  • h5fortran 简介与使用指南
  • vue前端面试题——记录一次面试当中遇到的题(1)
  • 冒险岛的魔法果实-多重背包
  • 关于有害的过度使用 std::move
  • SCADA|测试KingSCADA4.0信创版采集汇川PLC AC810数据
  • python学习打卡day50
  • A. Dr. TC
  • RPG24.设置武器伤害(二):将效果应用于目标
  • RabbitMQ可靠和延迟队列
  • 接收rabbitmq消息
  • 中心化交易所(CEX)架构:高并发撮合引擎与合规安全体系
  • [蓝桥杯 2024 国 Python B] 设计
  • TripGenie:畅游济南旅行规划助手:个人工作纪实(二十四)
  • Arduino入门教程:1、Arduino硬件介绍
  • LAN、WAN、WLAN、VLAN 、VPN对比
  • Java异步编程深度解析:从基础到复杂场景的难题拆解
  • 动态多目标进化算法:VARE(Vector Autoregressive Evolution)求解DF1-DF14,提供完整MATLAB代码
  • [服务器] Amazon Lightsail SSH连接黑屏的常见原因及解决方案
  • 东城建设网站/seo引流什么意思
  • 那个网站招丑的人做网红/百度推广怎么优化关键词的质量
  • 做网站 传视频 用什么笔记本好/友情链接交换网址大全
  • 呼和浩特市手机网站/免费建网站
  • 合肥网络科技有限公司做网站/开发网站用什么软件
  • 河东网站建设/新冠疫情最新情况最新消息