一次Unity引擎gal游戏TextMesh Pro字库汉化记录
一、原由受别人邀请接手了一个Gal的汉化,发现是Unity引擎的,并不是原版厂商常用的引擎。因为之前也没有接触过Unity,好一番折腾,总算是成了,记录一下曲折过程,顺便分享一下经验。
个人水平有限,写得不好还请多多谅解。
二、初步分析
从群友那里拿到游戏文件,双击直接可运行,不用破解,lucky~
进步一观察游戏资源,发现为Unity引擎:
进入Managed目录,发现是原版Mono打包的,没有用IL2CPP加密,lucky~,对我这种新手来说太好了。
网上搜索了一下,Unity引擎的脚步存放在Assembly-CSharp.dll中,没加密就是C#的,ILSpy安排上。
完美反编译,美滋滋~,代码保存成C#工程,计划通~
进一步分析游戏的资源的构成,发现StreamingAssets目录下有我们感兴趣的脚本封包
在保存的C#反编译项目中搜索 "script找到如下代码:
在这个类里继续往下翻,发现获取脚本的函数:
顺腾摸瓜,看看哪里调用了这个函数,发现是AssetManager.cs中的GetScriptData函数调用了它,继续回溯:
方框里就是脚本的读取了,包括string列表,这样脚本就解密完了,感觉很顺利呢,一天可以搞掂的样子~
三、曲折
写解包工具,提取了日文版的文本(这个版本是英文版的),测试顶一下,修改源代码,编译,一气呵成~
发现有很多框框,马上意识到是字库有问题,找找文字输出的函数吧,找了一会找到一个DisplayText函数,看起来像是 (人名,对话)
转到函数,发现NameArea和TextArea
转到定义,来到了class CStringEntity : MonoBehaviour,发现TextMeshPro TextObject,
进一步分析发现此时代码已经转到Assembly-CSharp-firstpass.dll中了,我意识到这可能是系统组件,网上搜索一番
果然,下面就是汉化字库就完成了,看起来还挺简单的,网上搜搜,看看有解决方案没有,还真找到了:
https://www.bilibili.com/video/BV1D5411V7MK
嗯,对着操作一番,首先下载unity,看起来要对应的版本才行,OK,主程序上属性一下,发现是Unity5.5版本的:
一般正规的软件厂商都会带版本信息,还是比较可靠的,下载,安装,一气呵成~,我,今天,就!要!搞!掂!它!
好的,安装TextMeshPro 插件,嗯,按网上说的进AssetStore搜索,嗯?怎么会没有?网友留了地址,点进去,嗯???怎么是404???
what fuck??
上管网搜索,好嘛,该软件已下架,我陷入了深深的思考。
没关系,面向百度编程嘛,找到一个 Text Mesh Pro U5.unitypackage的包,导入,安装,然后报错,修改,然后报错,看来是版本不对,再搜。
CSDNCSDNCSDN,好嘛,全是CSDN,没分,没钱。
偶然间找到一篇文章介绍 Text Mesh Pro的,了解到该字库最开始是由个人开发的收费软件,后来Unity官方觉得不错,收购了,从unity2018版起集成到了Unity引擎中,但是官方app依然提供下载。
俗话说得好,凡事都怕但是,看来2022年官方觉得这么多年过去了,是时候淘汰老版本了。
好嘛,没关系,梯--子打开,面向google编程,翻了两天英文网页,我终于找到了1.0.56 b21.0.56 b3 1.2.2版本for unity5.5unity5.6 unity2017.1unity2017.2 unity2017.3。
查了一下游戏发行时间2017年,1.0.56 b2安排上。
字库制作中,略过不表,网上教程很多,大同小异。
这里有一个选择,按照bilibili的教程,应该生成字库后提取,然后替换原来的字库,但是我看评论区有为朋友提到:
Font Asset Creator生成好字体(类型为TMP_FontAsset)后,做一个包含TMP_FontAsset的AssetBundle。
之后在代码中加载AssetBundle,获取你做好的TMP_FontAsset,直接替换掉游戏原本的字体。
我心动了,这种才是完美解决之道,才是程序应该做的,直接替换破坏了原来的数据,不好不好。
面向Unity编程,打包打包。
public static TMP_FontAsset chsFont;
public static void LoadChsFont() {
string chsfont = Path.Combine(Application.streamingAssetsPath, "CHS/jissdf");
LogPrint(chsfont);
AssetBundle assetBundle = AssetBundle.LoadFromFile(chsfont);
if (assetBundle != null) {
foreach (string tt in assetBundle.GetAllAssetNames()) {
LogPrint(tt);
}
chsFont = assetBundle.LoadAsset<TMP_FontAsset>("jisSDF");
if (chsFont != null) LogPrint("asset sucess! " + chsFont.GetType().ToString());
else LogPrint("faild,faild");
assetBundle.Unload(false);
}
else LogPrint("load AssetBundle faild");
}
运行,faild,修改,运行,faild faildfaildfaild,情况不对啊,在自己的Unity中运行,成功,嗯???
我悟了,看来是Text Mesh Pro的版本不对,我顿时有了一个大胆的想法,干嘛不引用新的Text Mesh Pro版本,把原来的Text Mesh Pro忽略掉,说干就干。
修改反编译的C#工程代码,引用 TextMeshPro-5.5-1.0.56-Runtime.dll,命名空间引用别名,解决命名冲突,编译,一气呵成~
load,成功!!!,yes~,进游戏测试,嗯?怎么文字全不显示了?继续改改,改改,还是不显示。好嘛,看来要多学一点Unity的知识,面向bilibili学习中。。。
四、解决
经过一番学习之后,我终于发现:Unity的场景工作模式是这样的,你要先再场景中放置一个对象,然后给对象绑定一个脚本,在脚本里编写你需要的代码。
回到游戏中,使用AssetStudio查看场景文件,发现场景中的对象是绑定了具体哪个dll程序集的,而且很多相关对象都是绑定了同一个程序集,
像之前那种移到另一个程序集,行不通,或者要改太多地方。
好嘛,还是得替换文件,而且我还发现,游戏里的TMP版本,跟我手头上有的还不一样!因为在VS中有提示某些函数已经废弃,看来游戏里的TMP版本,比我的要旧,
网上继续搜索,没找到。。。CSDN找到一个1.0.52的,淘宝六毛八下载下来。。。
安装,引用,嗯?这次发现VS中没有提示错误了,看来是这个版本了,顿时放心下来,看来是时候了!
这里说一下TMP字库的构成,使用AssetBundleExtractor查看生成的字库文件 *SDF.asset,有三个文件
MonoBehaviour保存了字库的基本信息,包括文字索引
Material保存了文字的效果,比如描边啊,阴影啊,Texture2D保存的是字库的图片,就是一张大大的图上写满了文字
OK,了解清楚我们照着视频操作,使用AssetBundleExtractor替换,保存,这里有个小细节,替换MonoBehaviour时必须首先点击ViewData,查看数据,并且弹射的第一个对话框选 “是”,后面的对话框根据有没有具体的dll选否,原理我们后面介绍。
替换完成,保存,运行,当然是成.....
崩溃了,崩溃了。
思考.jpg{:1_904:}{:1_904:}
why?
检查生成的封包,发现替换的 MonoBehaviour变成无法读取了,读取不出数据了。花了一段时间毫无营养的百度机器互相抄袭的答案后,我悟了。
我突然想起在反编译时看到的字段特性:
注意这个标识,C#拥有自动序列化的特性,只需要一个即可轻松序列化反序列化实例,再对照看看我们 AssetBundleExtractor 看到的信息,破案了兄弟们,
以及为什么 AssetBundleExtractor查看信息之前要寻找dll,就是通过反编译dll文件查找类属性,执行反序列化操作。自动序列化是一个好东西,但是这玩意是双刃剑,序列化是轻松了,
但是如果有任何字段的调整,比如添加新的序列化字段,之前序列化的东西就是无法再次在新的类上执行反序列化,表现出来的就是版本问题,版本不一样,你无法实现替换。
验证我的想法,AssetBundleExtractor导出老的TMP信息,和我生成的TMP版本信息,一比较,果然:
新生成的字库比旧的字库信息多出来几项,删掉它。
字库信息还比较接近,Material几乎就是面目全非了,完全没有修改的价值,好在游戏里的文字特效比较简单,就一个描边和阴影
了解了一下TMP的文字特效设置,找到阴影设置项
_UnderlayOffsetX是阴影的X轴偏移,同理Y是Y轴偏移,_UnderlaySoftness是阴影的虚化程度,这里我都改为0,因为已经有描边了,阴影效果不好,主要是我换了字体,原来的设置不适用。
修改完成后,导入,再测试,完美,收工收工,前前后后折腾了快一个礼拜了。
五、总结:
unity引擎汉化要特别注意版本问题,实在找不到原版本,找个差不多的版本来改吧。
文中并没有介绍各种工具的操作方法,具体使用百度上有很多了。
最后给大家分享一个我收集的各版本的Text Mesh Pro,不妨收藏一下,万一哪天用上了呢。
:lol
这个写的太好了,对于喜欢汉化的人,真的超级有帮助。 本帖最后由 shenhai555 于 2022-5-8 22:07 编辑
感谢
另外分享个GitHub上有个unitypyPython脚本
可以降级assetbundle文件
因为新版unity2019生成的assetbundle
无法在uabe中打开
我是先降级然后改完再升级 不然游戏必出错
不升级文件头部信息不一致会游戏报错 生命在于折腾,大佬辛苦了{:1_893:} 希望老大出个改攻击力的教程,之前的帖子有的。现在找不到了 misakanokaze 发表于 2022-2-16 14:48
这个写的太好了,对于喜欢汉化的人,真的超级有帮助。
有帮助就好,希望后来人少走点弯路 游戏汉化,厉害啊,修改游戏数据呢 大佬太强了 大部分都是我的知识盲区{:1_937:}{:1_937:}
提取了日文版的文本(这个版本是英文版的)
所以最后实现的效果是把英文替换成了日文,并没有汉化?
(对汉化完全不懂 二娃 发表于 2022-2-17 01:11
大佬太强了 大部分都是我的知识盲区
所以最后实现的效果是把英文替换成了日文,并没 ...
汉化要等翻译啊,程序处理好就行,无非就是替换文字。 学习了,学习了 学习一个