问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

记录一次汉化Unity游戏并手动去码的经过

创作时间:
作者:
@小白创作中心

记录一次汉化Unity游戏并手动去码的经过

引用
1
来源
1.
https://www.bilibili.com/read/mobile?id=34525871

本文详细记录了对Unity游戏进行汉化和去码的完整过程,从识别游戏版本、下载工具、翻译游戏到去除马赛克,每个步骤都进行了详细的说明,并附有具体的工具使用方法和注意事项。

最近发现一个游戏 RJ01181256,玩得很是上头,但是日语玩起来总是不爽,新游戏暂时也没有汉化包,就动了自己动手汉化的心思,由于之前没有接触过这方面,所以就稍微研究了下Unity游戏的汉化和去码是怎么做的
最终结果可喜可贺,两个目标都实现了,没有白费3个晚上掉的头发,在这里把思路和过程整理一下做个备忘,如果能帮到后来的人就更好了

  • 本文记录的方法只是分享一种方式和思路,不一定适用于所有Unity游戏和运行环境
    一、查看游戏Unity版本和运行时
    游戏exe右键属性,「详细信息 - 文件版本」一般就是Unity的版本,麻烦点也可以用十六进制打开游戏的场景(level0之类)或资产(sharedassets0.assets之类)文件,在靠近头部的地方就能看到引擎版本标识
    Unity游戏运行时一般有两种,MonoIL2CPP,由于性能和跨平台移植便捷性等原因,新游戏一般都是IL2CPP了,区分两者很简单,游戏目录有Assembly-CSharp.dll这个DLL就是mono,包含有il2cpp_data目录就是il2cpp
    Mono和IL2CPP的区别
    二、下载工具
    知道引擎版本就可以准备下载工具了,工具和操作方法和Unity版本相关,先看一遍各个工具的文档,确认版本可以支持
    这个游戏是Unity 2022.3.16f1 + IL2CPP的组合,起初找到的资料里的工具和方法很多只适用于旧版,踩了一些坑,所以在这里标注一下用到的工具:
    注意框架和插件文件名描述的版本号、框架类型、运行时和系统架构等信息,需要对应才能工作
    原版AssetStudio仅支持到2021,这里用了一个有人维护的fork分支,很多教程提到的UABE也只支持到2021,2022需要使用类似工具UABEA
    其中用的BepInEx#688版本还遇到了一个坑,下面汉化部分会细说
    三、翻译相关
    第一步:安装翻译插件
    按照BepInExXUnity.AutoTranslator的安装说明解压到游戏目录,然后运行一遍游戏,游戏启动会多出来一个命令行窗口,可以检查打印的日志,有插件相关的报错自行搜索解决
    插件成功加载
    第二步:修改插件配置,启用日译中
    上一步成功的话,进游戏已经可以看到游戏内的文本翻译成英文了,修改配置文件BepInEx\config\AutoTranslatorConfig.ini,把Language的值从en改成zh,其他的如Endpoint可以看插件文档自行修改
    Language的值改成zh
    重启游戏,机翻的翻译文件应该能在BepInEx\Translation\zh\Text_AutoGeneratedTranslations.txt找到,每行对应一条翻译
    第三步:提取和翻译
    由于是实时生成的翻译,所以如果想要覆盖到完整文本,就需要手动从头到尾玩一遍游戏,且不能快进(起码等到一句话的文本完全显示),不然可能会漏翻
    之后精翻调整等号=右边的内容即可,换行符和富文本标记符号需按原文格式填写,更多特性比如正则表达式支持可以看XUnity.AutoTranslator插件的文档
    解决游戏缺字,显示□□□的问题
    这是因为现代Unity游戏很多都使用了TextMeshPro组件(简称TMP字体)作为文字系统。TMP字体支持光照效果、Shader添加动效,且缩放无损、性能好所以很流行,但是TMP需要预先创建字符集,如果字符集未包含显示的字符则不会fallback到系统字体,而是会显示成字符。而很显然,一款日语游戏大概率是不会包含完整常用中文字符的,所以就需要给它提供一个字体作为替补,OverrideFontTextMeshProFallbackFontTextMeshPro配置项就是用来干这个的(注意这两个字段的起始目录是游戏根目录),所需的字体文件有两种方法获取:
    简单方法,XUnity.AutoTranslator插件作者同时提供了字体包TMP_Font_AssetBundles.zip可以直接使用,缺点是如果和游戏字形字重不一致,文字显示效果就会大小不一,只能说够用,不能解决好看的问题
    更高级的做法,是按照Unity的姿势,手动创建一个TMP字体:
  1. 官网下载Unity开发环境,不能高于游戏的版本,否则生成的字体可能加载失败
  2. 新建一个空白Unity场景,2D/3D不限制
  3. 把原始otf/ttf格式的字体文件拖到Assets窗口
  4. 选择「Window - TextMeshPro - Font Assets Creator」打开TMP字体创建工具
    打开TMP字体创建工具
  5. 创建工具的Source Font File值选择导入的原始字体文件,分辨率选择最大的8192*8192字符集根据情况选hex范围或者自定义字符列表,这里我用了《通用规范汉字表》收录的8105字加上常用标点共约8300作为字符集,其他参数参考下图填写
    需要注意字符数、Sampling尺寸选Auto、Packing方式选Optimum,和下面的Render方式等配置会大幅影响字体贴图生成速度,不当的生成配置可能需要数小时到数百小时的生成时间,图中配置生成耗费约5分钟
    一般在调整包含字符或Padding后的初次打包,需要把Sampling尺寸设置成Auto,由生成工具自动计算Sampling尺寸,后续打包可以用计算好的Sampling尺寸避免迭代计算的开销,各个参数作用可以自行搜索
    图中配置生成耗费约5分钟
  6. 生成结束后窗口滚动到最下面,点击Save保存SDF(Signed Distance Field)字体文件到Assets窗口。生成的文件名一般叫「xxx SDF.asset」
    可以在场景创建一个TextMeshPro 3D对象,关联SDF后输入文字内容来测试渲染
  7. 打开「Window - Package Manager」,搜索安装AssetBundle Browser组件,这是一个用来压缩打包资产的工具,也就是俗称的AB包,搜不到的话可以尝试从git安装
  8. 在Assets窗口分别选中原始字体和sdf字体,在右侧面板最下面AssetBundle工具栏里把它们关联到同一个AB包
  9. 打开「Window - AssetBundle Browser」,在Build页签构建一个AB包,构建会生成一个无后缀名文件,这个文件将就是翻译插件需要的sdf字体

    构建AssetBundle
  10. 到此已经成功打包出独有的sdf字体,配置到BepInEx\config\AutoTranslatorConfig.iniOverrideFontTextMeshProFallbackFontTextMeshPro,进游戏查看效果,一切顺利的话,此前缺失的文字就可以显示出来了
    !!!注意此处有坑 但是,上面说的BepInEx#688版本的坑点来了,我起初用这个版本在这步操作时老是遇到字体加载报错,经过包括但不仅限于换用更低版本的Unity/TextMeshPro/AssetBundle等、尝试用Melon loader(另一种插件框架),耗费n根头发后得出结论:上面的操作完全不影响报错😀 问题不在字体本身,而在插件上面
    TMP字体加载失败
    于是继续控制变量挨个版本试过去,最终在BepInEx#671或666之间的某个版本,TMP字体可以成功加载了,再升级到688版本后也没继续报错,原因猜测是BepInEx初次运行时会在BepInEx目录下载一些Unity的dll,而不同版本的dll二进制并不一致,可能就在某个版本后的dll未包含加载字体需要的方法,或者方法改名,导致加载失败。总之如果遇到类似问题,这可能是个思路
    四、去码
    众所周知马赛克是万恶之源,阻挡了人类文明探索世界的脚步,我们接下来就干掉它,去码同样有自动和手动两种操作:
    自动去码
    需要插件:UniversalUnityDemosaics
    需要前置安装BepInEx,下载插件并解压到BepInEx\plugins目录,启动游戏,再看看之前打码的区域,不好意思我先去趟厕所🥵
    自动方式用起来轻松愉快,但可能造成误伤,比如本游戏的相机道具就会造成相机画面消失,那么就需要手动修改达成效果
    手动去码:
    需要工具:Il2CppDumper、AssetStudioMod、UABEA
    基本思路:
  11. Il2CppDumper加载GameAssembly.dll、global-metadata.dat文件,导出dll到游戏data目录下手动新建的Managed目录
  12. AssetStudio加载游戏目录,提示选择dll目录就选择刚才的Managed目录
  13. 搜索mosa、mosaic、mozaic、censor、pixelate等关键词,记下所在文件和PathID
    谜之物体
  14. 在UABEA中加载对应资源文件,如果已经完成了第一步,需要先关闭UABEA的Cpp2IL功能,提示Use Cpp2Il is set to: false就可以了
    关闭Cpp2IL
  15. 找到对应PathID的内容,Mesh可以直接删除,ShaderMonoBehaviour就修改参数
    此处需要发挥一点想象力猜来测参数作用,比如这款游戏的相机道具靠近某些位置时,会在相机镜头前叠加一个马赛克滤镜,如果直接把enabled改为0反而会一直显示滤镜,这时选择把生效距离改为0就可以实现去码功能
    永远无法到达马赛克的真实
  16. 保存回游戏确认效果,需要注意UABEA只能另存为然后手动替换,不能直接修改打开的文件
    总结
    让GPT帮我总结一下:
    这篇文章记录了作者如何对Unity游戏进行汉化和去码的详细过程。主要步骤包括:
  17. 识别游戏版本和运行时:通过游戏exe文件或场景/资产文件查看Unity版本,判断游戏是使用Mono还是IL2CPP。
  18. 下载和使用工具:根据Unity版本选择并下载合适的工具和插件,包括BepInEx、XUnity.AutoTranslator、UniversalUnityDemosaics、Il2CppDumper、AssetStudioMod和UABEA等。
  19. 翻译游戏:安装翻译插件,修改配置文件实现日译中,通过手动游玩游戏生成完整翻译文本,通过修改AutoGeneratedTranslations.txt文件进行精翻,对于缺字问题提供简单和高级两种解决方案,详述了高级方案中创建自定义TMP字体的方法和注意事项。
  20. 去除马赛克:提供自动和手动去码方法,自动去码使用UniversalUnityDemosaics插件,手动去码则通过Il2CppDumper、AssetStudioMod和UABEA工具修改相关资源文件。
    此外,文章还分享了作者在工具使用过程中遇到的问题和解决方法,特别是BepInEx不同版本在加载TMP字体时的兼容性问题,给出了具体的调试和解决思路。
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号