Unity UGUI汉化方案:Unity UI Translation (UITL & UITI)

Unity UI Translation Loader(简称UITL)是由HongFire和Anime-Sharing论坛的akyryz为了英化黄油(不要问我英化黄油是什么黄油,好吃吗)而制作的一个Unity游戏本地化方案,由一个类库UnityEngine.UI.Tranlation.dll和修改过的Unity引擎库UnityEngine.dll、UnityEngine.UI.dll组成。其核心思想是让Unity在执行到引擎库里的某些方法(比如一个Text或者Texture加载时)时调用到UnityEngine.UI.Tranlation,而这个库会在本地查找这些对象有没有翻译版本的对应素材,如果有则替换成翻译版本,再返回到引擎库的正常执行过程(这个过程类似于Hook);或者(翻译模式)将这些文本、图片(名称)导出到文件等待翻译。他已经将这一方案用在SBPR以及最近很火的HS上。

此方案的优点:对翻译者非常方便。只需运行游戏就能获得文本,文本的格式统一,用文本编辑器即可修改,修改完再运行游戏即可查看效果。此外还能支持图片和声音的替换,甚至对声音添加字幕。一个没有本地化考虑的游戏仿佛就此具有了本地化功能。

此方案的缺点:

  • 除了文本之外不能直接导出其他素材(如图片),只能通过名字手动导出对应的素材并修改(但可以直接加载修改后的素材而不需手动替换回游戏文件)。今后对此应当进行改进。
  • 获取到的文本是显示文本,而不是程序文本。有些游戏采用打字机式的对话输出,就会导致文本大量冗余。此外对于程序诸如“你的名字是:{0}”这样的参数字符串可能难以处理。(不过另一方面来说,此方案特别适合处理保存在资源中的或是加密过的文本。)
  • 需要修改Unity的引擎DLL。
  • UITL实现时为了读取INI文件,使用了Windows API。这是不科学的,必须得改。
  • 喂喂,你怎么能在UnityEngine.dll里引用UnityEngine.UI.Tranlation.dll,又在UnityEngine.UI.Tranlation.dll里引用UnityEngine.dll,这样的代码不是辣鸡吗?(笑)——按照软件工程的标准来看确实不应如此,但此处只有这样才能实现。

文本问题:比如游戏中有这样一个逐字显示的文本

う、うぅ……、ここは? = 唔、呜呜……这里是?

 在UITL中就会Dump出以下文本:

う =
う、 =
う、う =
う、うぅ =
う、うぅ… =
う、うぅ…… =
う、うぅ……、 =
う、うぅ……、こ =
う、うぅ……、ここ =
う、うぅ……、ここは =
う、うぅ……、ここは? = 

 

此方案需要修改Unity引擎的DLL,包括UnityEngine.dll和UnityEngine.UI.dll。但是akyryz只提供了几个黄油版本的DLL,并没有给出通用的方案。这么有趣的方案只用于黄油,还是挺可惜的。于是我从其实现(UnityEngine.UI.Translation)出发,制作了UITI:Unity UI Translation Injector。项目见github:https://github.com/UlyssesWu/UnityEngine.UI.Translation

UITI的作用是修改Unity游戏的引擎DLL,使其能与UITL协同工作。UITL的一些实现细节让我感到很有意思,比如为了修改UnityEngine.AudioSource(位于UnityEngine.dll)的Play方法(此方法被标记为外部实现,即没有方法体,在运行时由mono绑定到native方法),竟然构造了一个同名的UnityEngine.AudioSource(位于UnityEngine.UI.Translation.dll)作为前者的基类,在其中构造Play方法,以完全相同的名字(UnityEngine.AudioSource.Play)欺骗mono,使mono把这个基类的Play方法绑定到了native方法,而原来的Play方法就可以随意修改了。不过这也引出了编程时的问题:引入的两个不同的DLL中具有【同样的命名空间名】和【同样的类型名】的类型该怎么区分?答案是使用extern alias,详见代码。

效果图:

 

这里其实还有一个问题,看截图可能也发现了:原游戏中使用的日语字体没有简体汉字。为了使其显示简体汉字,我改了游戏的字体。目前UITL还没有这个功能(英化一般不考虑修改字体,汉化却经常需要考虑),这也是接下来可以考虑增加的一个功能。为了修改本游戏的字体,我为另一款黄油工具SB3U写了一个简单的插件使其支持导出和修改字体,这个留待以后讨论。

评论 (5) -

  • RMB
    U酱果然好强啊..
  • 在网上找了很久找到博主的文章有提及汉化字体的事,结果看到结尾说留待以后讨论,想着有希望了,但是看了看这文时间和博主之后再无更新.....
    • 这个……因为之前异常地闲所以有空搞些别的东西,但是最近变得忙起来了,而且以后工作可能会更加的忙了。

      首先说明一点,这里针对的是ttf/otf的字体(而不是贴图字体,那种通常需要同时替换贴图和字体定义文本)。因为SB3U这个工具是可以替换素材的,但不能替换ttf/otf,于是我顺手把这个功能加上了(同时也感受到SB3U、UnityStudio等这些工具的代码架构真是太混乱啦,本想开个坑但是忙起来了)。如果你正是需要这个【SB3U下的ttf替换功能】,可以留个邮箱,我发给你。
  • 感觉对字库的支持不是很好现在的游戏变动太多,艺术字体图集字库越来越多干脆就没有ttf类型的字体了==如果可以类型的图集字库配置文件就好了,
    • 作为程序,我认为多数情况下使用ttf/otf比起位图字体会更好,“游戏变动太多”的情况用ttf反而是更好的——比如更新版本的时候要把某条文本换掉,如果这时候你的字体贴图没有新文本里的某个字,那就尴尬了。字体文件多出来的那点空间占用对游戏影响不大。(艺术字完全可以通过在ttf渲染时加特效解决。)
      当然,本文提及的方案重点是程序内文本的汉化,至于换字体那是属于资源处理方面的问题。(毕竟这个方案的原作者的目的是英化,不存在换字体的考虑。)当然,你完全可以像换ttf一样换掉位图字体定义文件和字体贴图(由于用到的中文字可能会比较多,极有可能要添加贴图),这都是可以做到的。目前我没有参与这样的项目,也就没有去做。

添加评论

Loading