1. 项目概述:为什么我们需要游戏自动翻译工具?
如果你是一个喜欢玩独立游戏或者小众Unity游戏的玩家,肯定遇到过这样的烦恼:一款游戏玩法绝佳,美术风格独特,但偏偏没有中文。面对满屏的英文、日文或者其他语言,查字典查到心累,剧情体验大打折扣,最后只能无奈放弃。同样,对于游戏开发者而言,尤其是独立开发者,为游戏添加多语言支持是一项耗时耗力的工程,需要处理文本提取、翻译、导入、测试等一系列繁琐步骤,成本高昂。
XUnity Auto Translator正是为了解决这个痛点而生的神器。它不是一个简单的文本替换工具,而是一个运行在游戏进程内的、功能强大的实时翻译框架。它的核心原理是“钩子”(Hooking)技术,能够拦截游戏引擎(主要是Unity)在运行时向屏幕绘制文本的调用,将原始文本替换为你指定的翻译文本,从而实现“所见即翻译”的效果。这意味着,你不需要修改游戏本体的任何文件,也不需要等待官方发布补丁,就能即时享受母语游戏体验。
这个工具在玩家社区中早已不是秘密,但对于很多刚接触的朋友来说,其配置过程略显复杂,涉及运行库、插件、规则文件等多个环节。网上能找到的教程往往零散、过时,或者只针对某一款特定游戏。本文将扮演一个“引路人”的角色,结合我多年折腾各种Unity游戏汉化的经验,为你提供一份从原理到实战,从安装到排错的完整指南。无论你是想为自己心爱的游戏“啃生肉”,还是想研究其技术实现,这篇文章都将为你铺平道路。
2. 核心原理与架构拆解:它如何实现“无痕”翻译?
在深入实操之前,理解XUnity Auto Translator(下文简称XUAT)的工作原理至关重要。这不仅能帮助你在遇到问题时快速定位,也能让你明白其能力的边界和潜在风险。
2.1 核心机制:运行时文本拦截与替换
Unity游戏在屏幕上显示的文字,绝大多数是通过其UI系统(如uGUI、TextMeshPro)或传统的GUI.Label、GUIText组件来绘制的。这些组件在渲染前,会调用底层图形API(如Direct3D或OpenGL)提交包含文字信息的纹理或指令。
XUAT的核心是一个用C#编写的插件,它通过BepInEx、MelonLoader或UnityDoorstop等通用Mod加载器注入到游戏进程中。一旦成功注入,XUAT便会使用“钩子”技术。具体来说,它利用了Harmony这样的库,对Unity引擎中负责最终文本渲染的关键函数进行“打补丁”(Detouring)。
例如,它可能会钩住TextMeshPro.TextMeshProUGUI.OnEnable或UnityEngine.UI.Text的文本设置属性。当游戏试图设置或显示一段文本时,XUAT的代码会先一步被调用。此时,插件会:
- 捕获:获取游戏原本要显示的原始文本字符串。
- 查询:将这段原始文本作为“键”,去查询一个预先准备好的翻译词典(通常是一个
.txt或.po文件)。 - 替换:如果词典中存在对应的翻译,则用翻译文本替换原始文本;如果不存在,则可以选择保持原样、留空,或者调用在线翻译API(如谷歌翻译、百度翻译、DeepL)进行实时翻译并缓存结果。
- 放行:将处理后的(可能是已被翻译的)文本交还给Unity引擎进行正常渲染。
整个过程发生在内存中,对游戏本体的文件是只读的,因此通常不会破坏游戏完整性,在关闭翻译插件后游戏即恢复原状。
2.2 插件架构与核心组件
一个完整的XUAT工作环境通常包含以下几层:
- Mod加载器层:这是基石,负责将非官方的C#插件(即XUAT)加载到Unity游戏进程中。
BepInEx是目前最主流、兼容性最好的选择,本文也将以其为例。 - 翻译框架层:即XUAT插件本身。它提供了翻译的核心逻辑、配置界面和API。它负责管理钩子、加载词典、与在线服务通信等。
- 资源文件层:
- 翻译词典文件:存放着“原文-译文”的对应关系。最常见的是
Translation.txt,格式为原文<|>译文。也有支持.po(Gettext格式)、.json等格式的扩展插件。 - 字体文件:很多游戏使用的字体不包含中文(或其它目标语言)的字形。XUAT可以强制指定一个备用字体来显示翻译后的文字,你需要将相应的
.ttf或.otf字体文件放在指定目录。 - 配置文件:
BepInEx和XUAT都有自己的配置文件(BepInEx.cfg,AutoTranslatorConfig.ini),用于控制插件行为、启用功能、设置API密钥等。
- 翻译词典文件:存放着“原文-译文”的对应关系。最常见的是
2.3 在线翻译与离线翻译的抉择
XUAT支持两种主要的翻译模式,各有优劣:
- 在线翻译:配置谷歌、百度、DeepL等服务的API后,可以实现全自动、无需词典的实时翻译。优点是“开箱即用”,覆盖所有文本。缺点也很明显:翻译质量不稳定,尤其是对游戏特有的术语、人名、技能名可能翻译得啼笑皆非;存在延迟,每次遇到新文本都需要联网请求;可能有调用次数限制或费用(虽然个人使用通常不会超限)。
- 离线翻译:完全依赖本地加载的
Translation.txt词典文件。优点是翻译质量高、风格统一、零延迟。缺点是需要有人事先制作并维护词典,对于新游戏或更新频繁的游戏,词典可能不完整。
我的实操心得:对于剧情向、文字量大的游戏,强烈建议寻找或制作离线词典。对于UI文本、物品名称等固定内容,离线词典能提供最佳体验。可以将两者结合:优先使用离线词典,对于词典中缺失的文本,再启用在线翻译作为补充,并将在线翻译的结果导出,逐步完善自己的离线词典。这是一种“众筹”式的高质量汉化思路。
3. 环境部署与工具链搭建
工欲善其事,必先利其器。为Unity游戏安装翻译插件,第一步是搭建一个稳定可靠的环境。下面以最通用的BepInEx + XUAT组合为例,详细说明每一步。
3.1 第一步:识别你的游戏环境
在动手前,必须搞清楚三件事:
- 游戏使用的Unity版本:这决定了你需要什么版本的BepInEx。可以通过查看游戏根目录下
UnityPlayer.dll的文件属性-详细信息中的“产品版本”来推测,或使用工具UnityEX来查看。 - 游戏是32位(x86)还是64位(x64):查看游戏主exe文件的属性。现代游戏以64位居多。
- 游戏是否使用了Mono还是IL2CPP后端:IL2CPP是Unity将C#代码转换为C++再编译的技术,安全性更高,需要特殊版本的BepInEx。通常,较新的、有反作弊需求的游戏可能使用IL2CPP。一个简单的判断方法是:查看游戏目录,如果存在
GameAssembly.dll(IL2CPP) 和UnityPlayer.dll,而没有Assembly-CSharp.dll(Mono),那么很可能就是IL2CPP。Mono则相反。
注意:对于IL2CPP游戏,你需要使用
BepInEx Unity IL2CPP版本,其安装和配置与标准Mono版略有不同,后续步骤会特别指出。
3.2 第二步:安装BepInEx Mod加载器
- 下载:访问BepInEx的GitHub发布页。根据你的游戏架构(x86/x64)和脚本后端(Mono/IL2CPP)下载对应的
BepInEx_x64_版本号.zip或BepInEx_IL2CPP_x64_版本号.zip。 - 安装:将压缩包内的所有文件解压到游戏的根目录(即与游戏主exe文件同一目录)。确保
doorstop_config.ini,winhttp.dll,BepInEx文件夹等都被正确放置。 - 首次运行验证:启动一次游戏,然后退出。此时游戏根目录下应该会生成完整的
BepInEx文件夹结构,包含plugins,config,patchers,core等子目录。如果没生成,可能是版本不匹配或游戏有特殊的启动器保护。
3.3 第三步:安装XUnity Auto Translator插件
- 下载插件:从GitHub或相关Mod站获取最新版的
XUnity.AutoTranslator插件。通常是一个名为XUnity.AutoTranslator-BepInEx-5.x.x.x.zip的压缩包。 - 放置插件:将压缩包内的
Translation文件夹和XUnity.AutoTranslator.dll文件,复制到BepInEx/plugins目录下。 - 安装依赖:XUAT通常依赖
XUnity.Common和XUnity.ResourceRedirector这两个基础库。确保它们也被放置在了BepInEx/plugins目录下。通常插件包会一并包含。
3.4 第四步:基础配置与字体准备
- 生成配置文件:再次启动游戏并退出,让XUAT生成默认的配置文件。配置文件位于
BepInEx/config/AutoTranslatorConfig.ini。 - 配置核心选项:用文本编辑器打开
AutoTranslatorConfig.ini,关注以下几个关键项:[General]章节下的Language:设置为zh(中文)。[Service]章节:选择在线翻译服务。例如,使用百度通用翻译,需将Endpoint设为Baidu,并在下方[Baidu]章节配置你的AppId和SecretKey(需要去百度翻译开放平台免费申请)。[Behaviour]章节:SkipAlreadyTranslatedText建议设为true,避免重复翻译;MaxCharactersPerTranslation可根据服务商限制调整。
- 准备中文字体:在游戏根目录或
BepInEx/Translation文件夹下,创建一个Fonts文件夹。将你想要使用的中文字体(如“方正准圆_GBK.ttf”、“霞鹜文楷.ttf”)复制进去。然后在配置文件的[Font]章节,设置FontNames为你字体文件的名称(不含路径,如方正准圆_GBK)。
4. 翻译词典的创建、使用与高级管理
离线词典是高质量翻译的基石。即使你主要使用在线翻译,学会管理词典也能极大提升体验。
4.1 词典文件格式详解
XUAT最常用的词典格式是纯文本的Translation.txt,其基本规则是:
原文<|>译文例如:
Start Game<|>开始游戏 Load Game<|>读取存档 Save Game<|>保存游戏每一行一条记录,<|>是分隔符,前后不要留空格。译文部分可以包含换行符\n。
更高级的用法是使用.po文件格式,它被专业本地化工具广泛支持(如 Poedit)。.po文件结构更清晰,支持译者注释、上下文信息,便于团队协作。XUAT有专门的插件来支持.po文件。
4.2 如何获取与制作词典
- 社区寻找:在GitHub、贴吧、相关游戏论坛搜索 “游戏名 + XUnity 汉化” 或 “游戏名 + Translation.txt”。很多热心玩家会分享他们的成果。
- 导出在线翻译结果:这是从零开始制作词典的最佳方式。在配置文件中启用
[Behaviour]下的EnableTranslationHelper和EnableSubtitle。在游戏中,所有被翻译的文本都会在屏幕一角显示原文和译文。同时,XUAT会将所有在线翻译的结果自动保存到BepInEx/Translation/游戏名/GeneratedTranslations.txt。你可以将这个文件重命名为Translation.txt作为离线词典的基础,然后进行人工校对和润色。 - 手动提取与翻译:对于没有在线翻译的小文本量游戏,可以使用Unity资源解包工具(如
AssetStudio)提取游戏内的文本资源(通常位于resources.assets或sharedassets*.assets中),整理成原文列表,在翻译软件中处理后再格式化为Translation.txt。
4.3 词典的加载优先级与合并
XUAT支持多个词典文件,并按照一定优先级加载,这为模块化管理提供了便利:
Translation/游戏名/Text/目录下的Translation.txt(最高优先级)。Translation/Text/目录下的Translation.txt(全局词典)。- 插件内置或在线翻译(最低优先级)。
你可以利用这个特性:将游戏通用的UI文本(如“OK”、“Cancel”、“Start”)放在全局词典里;将某个游戏特有的剧情文本放在其专属目录下。当多个词典对同一原文有不同译文时,优先级高的会覆盖优先级低的。
注意事项:编辑词典后,需要重启游戏或按XUAT的热键(默认F8)重新加载词典才能生效。确保词典文件使用UTF-8编码保存,否则中文会出现乱码。
5. 实战全流程:以一款典型Unity游戏为例
让我们以一款假设的、使用Unity Mono后端、x64架构的独立游戏《Fantasy Quest》为例,完成一次完整的汉化实战。
5.1 环境准备与插件安装
- 定位《Fantasy Quest》的安装目录,例如
D:\Games\FantasyQuest。 - 根据游戏版本(例如Unity 2019.4.x),下载对应的
BepInEx_x64_5.4.21.0.zip,解压所有文件到游戏根目录。 - 下载
XUnity.AutoTranslator-BepInEx-5.8.0.zip,将其中的plugins文件夹内容合并到BepInEx/plugins。 - 首次启动游戏,出现BepInEx控制台窗口并正常进入游戏后退出。
5.2 配置翻译服务与字体
- 打开
BepInEx/config/AutoTranslatorConfig.ini。 - 将
Language改为zh。 - 在
[Service]部分,设置Endpoint=Baidu。 - 申请百度翻译API(免费),获得AppId和SecretKey,填入
[Baidu]部分。 - 将下载好的
方正准圆_GBK.ttf放入BepInEx/Translation/Fonts/。 - 在
[Font]部分,设置FontNames=方正准圆_GBK,DefaultFontSize=28(根据游戏UI调整)。
5.3 启动游戏与初步测试
- 重新启动游戏。如果一切正常,游戏内的英文文本应该会逐渐被替换成中文(首次翻译需要联网,会有短暂延迟)。
- 观察翻译质量。可能会发现“Fireball”(火球术)被译成了“火球”,“Mana”(法力值)被译成了“玛娜”。对于游戏术语,在线翻译往往不尽人意。
5.4 创建与优化离线词典
- 玩一段时间,让XUAT生成足够的翻译缓存。退出游戏。
- 找到
BepInEx/Translation/FantasyQuest/GeneratedTranslations.txt,将其复制一份,重命名为Translation.txt。 - 用文本编辑器(如VSCode、Notepad++)打开这个
Translation.txt,开始人工校对。例如:- 将
Mana<|>玛娜改为Mana<|>法力值 - 将
Fireball<|>火球改为Fireball<|>火球术 - 将
A powerful spell that...<|>一个强大的法术...根据剧情上下文润色为更符合奇幻文学风格的译文。
- 将
- 校对完成后,保存文件。重启游戏,按F8重载词典。现在,游戏内的术语和剧情翻译应该已经是你校对后的高质量版本了。
5.5 处理特殊UI与图片文本
有些游戏的文本是直接绘制在贴图上的(如图标上的文字),或者使用了Sprite字体,XUAT无法直接翻译。对于这种情况:
- 贴图文本:需要借助
XUnity.ResourceRedirector的资源重定向功能,用翻译好的图片替换原图。这需要一定的图像处理能力。 - Sprite字体:XUAT的字体替换功能有时可以解决,如果不行,可能需要更底层的补丁或等待游戏更新UI系统。
6. 常见问题排查与性能优化指南
即使按照步骤操作,也难免会遇到问题。下面是一些常见故障及其解决方法。
6.1 插件加载失败
- 症状:游戏启动无BepInEx控制台,或控制台提示XUAT加载错误。
- 排查:
- 检查BepInEx版本是否与游戏Unity版本、架构匹配。对于IL2CPP游戏,必须使用IL2CPP专用版。
- 检查
winhttp.dll和doorstop_config.ini是否正确放置。对于某些通过启动器(如Steam)运行的游戏,可能需要修改doorstop_config.ini中的targetAssembly路径,或使用UnityDoorstop的特定配置。 - 检查游戏是否自带反作弊或文件完整性校验(如EasyAntiCheat)。这类游戏通常无法安装任何插件,强行安装可能导致封号。
6.2 游戏内无翻译效果
- 症状:游戏能正常启动,BepInEx控制台也显示XUAT已加载,但游戏内文字毫无变化。
- 排查:
- 检查
AutoTranslatorConfig.ini中的Language是否设置正确。 - 检查在线翻译服务是否配置正确,API密钥是否有效、是否超额。可以暂时切换到
GoogleTranslate(无需密钥但可能不稳定)测试。 - 检查字体配置。如果字体名错误或字体文件损坏,翻译文本可能无法显示(表现为空白)。尝试关闭字体替换功能,看基础翻译是否出现。
- 该游戏可能使用了非常规的文本渲染方式(如自定义Shader、文本即网格),XUAT的默认钩子可能无法捕获。需要社区提供针对该游戏的特定补丁或更新XUAT版本。
- 检查
6.3 翻译乱码或字体显示异常
- 症状:翻译出的中文显示为方框“□□□”或乱码。
- 解决:
- 方框:绝对是字体问题。确保字体文件包含中文字形,且字体名在配置中拼写正确。尝试换一个字体。
- 乱码:通常是编码问题。确保所有的配置文件(.ini)和词典文件(.txt)都以UTF-8 without BOM的编码格式保存。Windows记事本默认保存的UTF-8是带BOM的,可能导致问题,建议使用VSCode、Notepad++等编辑器并明确设置编码。
6.4 游戏崩溃或性能下降
- 症状:游戏在特定场景(如打开背包、对话)时崩溃,或明显变卡。
- 排查:
- 崩溃:查看BepInEx控制台最后输出的错误信息。可能是XUAT与某个游戏模组冲突,或钩住了不稳定的函数。尝试禁用其他所有Mod,只开XUAT测试。在配置文件中关闭
EnableTextureTranslation等高级实验性功能试试。 - 性能下降:在线翻译有网络延迟;庞大的离线词典文件加载会占用内存;字体替换会增加渲染开销。对于性能敏感的游戏,可以:①使用精校过的、去重后的离线词典,减小文件体积;②关闭“实时翻译缓存”等非必要功能;③在配置中增大翻译延迟
DelaySeconds,减少同一帧内的翻译请求。
- 崩溃:查看BepInEx控制台最后输出的错误信息。可能是XUAT与某个游戏模组冲突,或钩住了不稳定的函数。尝试禁用其他所有Mod,只开XUAT测试。在配置文件中关闭
6.5 在线翻译服务不可用
谷歌、百度等服务的免费API可能有访问频率限制或地域限制。
- 备用方案:在配置文件中预设多个服务端点(Endpoint),如
GoogleTranslate, Baidu, DeepL,并设置FallbackEndpoint。当主服务失败时自动切换。 - 本地部署:对于高级用户,可以考虑部署开源的翻译模型(如
argos-translate)在本地,并将XUAT配置为调用本地API,实现完全离线、私密的翻译,但需要一定的技术能力和硬件资源。
折腾的过程本身就是一种乐趣。从看到满屏外文不知所措,到成功让游戏界面变成熟悉的母语,这种成就感是独特的。更重要的是,在这个过程中,你实际上窥探了游戏运行的一角,理解了Mod社区是如何运作的。或许某一天,你校对好的那份Translation.txt,也会被分享出去,帮助到另一个被语言困扰的玩家。这就是开源与共享的魅力所在。