Unity游戏自动翻译插件XUnity.AutoTranslator:从原理到实战配置指南
1. 项目概述为什么你的Unity游戏需要一个自动翻译器如果你是一名独立游戏开发者或者是一个热衷于体验全球各地优秀Unity游戏的玩家那么语言障碍很可能是一个绕不开的痛点。想象一下你精心打磨的游戏因为语言问题而无法触达更广阔的海外市场或者你发现了一款玩法精妙的日文、韩文游戏却因为看不懂剧情和UI而无法深入体验。手动汉化或翻译那意味着你需要反编译游戏、定位文本资源、逐句翻译再重新打包不仅技术门槛高而且过程极其繁琐对于文本量大的游戏来说几乎是不可能完成的任务。这正是XUnity.AutoTranslator这类插件存在的意义。它不是一个简单的文本替换工具而是一个运行在游戏进程内的、实时的、高度可配置的自动翻译框架。它的核心原理是通过“钩子”Hooking技术拦截Unity引擎在运行时对文本组件的赋值操作比如Text.text或TextMeshPro的文本设置将原始文本发送到配置好的翻译服务如谷歌翻译、百度翻译等获取翻译结果后再动态替换回游戏界面。整个过程对游戏本身几乎无感玩家只需要安装插件、选择目标语言就能立刻看到翻译后的内容。对于开发者而言它意味着你可以快速为你的游戏制作多语言原型测试不同语言下的UI适配情况对于玩家和模组制作者它则是打开非母语游戏大门的万能钥匙。我接触过不少使用Unity制作的视觉小说、RPG和模拟经营类游戏文本量动辄数十万上百万字手动翻译的工程量是天文数字。而XUnity.AutoTranslator配合在线翻译API可以在几小时内完成整个游戏文本的初步翻译虽然机翻质量可能不尽如人意但足以让你理解游戏的核心内容和玩法后续再通过其强大的手动翻译文件功能进行精细化校对和润色效率提升了不止一个量级。2. 核心需求解析从安装到配置你需要知道的一切在开始动手之前我们首先要明确自己的需求。XUnity.AutoTranslator功能强大但并非所有功能对每个用户都是必需的。根据我的经验用户主要分为以下几类他们的核心需求也各不相同1. 普通玩家只想玩游戏核心需求以最简单、最稳定的方式将一款特定的非母语游戏翻译成自己能看懂的语言。关键动作找到针对该游戏预配置好的翻译插件整合包通常由社区爱好者制作解压到游戏目录即可。他们可能不需要也不应该去修改复杂的配置文件。2. 进阶玩家/模组译者想翻译特定游戏并分享成果核心需求为某款游戏配置翻译插件并利用其自动翻译和手动校对功能生成高质量的翻译补丁甚至替换游戏内的图片资源如UI图标、菜单。关键动作需要深入理解插件的配置文件Config.ini熟练配置翻译端点如DeepL、百度翻译API管理自动生成的翻译文件并可能启用纹理图片替换功能。3. 游戏开发者为自己的游戏集成多语言支持核心需求将XUnity.AutoTranslator作为开发工具快速实现游戏文本的国际化i18n或者为模组作者提供一个官方的翻译支持框架。关键动作需要研究插件的API了解如何让插件不干扰自己游戏特定的UI逻辑通过XUAIGNORE标记甚至为其开发自定义的资源重定向器Resource Redirector。4. 插件开发者希望扩展翻译器功能核心需求为插件添加新的翻译服务支持如接入了某小众但精准的翻译API或开发新的资源处理模块。关键动作需要理解ITranslateEndpoint接口或ResourceRedirectionAPI并按照规范进行开发。无论你属于哪一类第一步都是相同的正确安装插件。XUnity.AutoTranslator本身不直接运行它需要依赖一个“插件管理器”来加载。目前主流支持三种管理器BepInEx最通用社区支持最广、IPA主要用于Illusion系的游戏和ReiPatcher较老。对于绝大多数Unity游戏BepInEx是你的首选。安装步骤通常是先安装BepInEx到游戏根目录然后将XUnity.AutoTranslator的插件文件XUnity.AutoTranslator-BepInEx-5.x-xxx.zip中的内容解压到BepInEx\plugins目录下。启动游戏后在游戏根目录的BepInEx\config文件夹中就会生成AutoTranslatorConfig.ini配置文件这意味着插件已成功加载。注意插件的版本必须与BepInEx的版本匹配。例如BepInEx 5.x 需要使用插件包名中带有“BepInEx-5”的版本而BepInEx 4.x则需要使用对应的4.x版本否则会导致加载失败。下载时务必看清压缩包名称。3. 核心配置详解让翻译器按你的想法工作安装成功后真正的“魔术”都发生在AutoTranslatorConfig.ini这个配置文件里。这个文件看似复杂但我们可以将其分解为几个核心模块来理解。首次运行后建议用文本编辑器如Notepad、VSCode打开它进行配置。3.1 基础设置与翻译端点配置配置文件的第一部分[General]和[Service]决定了翻译器的基本行为和翻译源。[General] Languagezh-CN ; 目标语言例如 zh-CN (简体中文) ja (日语) en (英语) [Service] EndpointGoogleTranslate ; 翻译服务。可选值包括GoogleTranslate, GoogleTranslateLegitimate, BingTranslate, BaiduTranslate, DeepLTranslate 等。 ; 留空或设为 None 则禁用自动翻译。Language这是最重要的设置之一决定了翻译的目标语言。必须使用标准的语言代码如zh-CN、en、ja。插件会根据此代码寻找对应的翻译文件目录例如Translation\zh-CN\。Endpoint选择在线翻译服务。GoogleTranslate是默认的免费服务但可能不稳定或受网络限制。BaiduTranslate和GoogleTranslateLegitimate需API密钥是更稳定可靠的选择。如果你有相应的API密钥强烈建议使用后者以获得更好的服务质量和请求配额。关于翻译端点的选择与API配置GoogleTranslate免费无需配置开箱即用但可能因网络问题无法连接或速度慢。它通过模拟网页请求工作存在被屏蔽的风险。BaiduTranslate / GoogleTranslateLegitimate / DeepL这些是官方API需要申请API Key并配置。以百度翻译为例你需要在[Baidu]段落填写BaiduAppId和BaiduAppSecret。[Baidu] BaiduAppId你的AppID BaiduAppSecret你的密钥然后在[Service]中将Endpoint改为BaiduTranslate。官方API的翻译质量通常更稳定且有更高的请求频率限制。重要提醒绝对不要在公开发布的翻译整合包中配置你自己的私人API密钥。这会导致他人滥用你的配额产生高额费用。社区发布的整合包通常使用免费端点或引导用户自行配置API。3.2 文件与缓存管理[Files]和[Behaviour]部分控制着翻译文件的存储、加载和插件的基础行为。[Files] DirectoryTranslation\{Lang}\Text OutputFileTranslation\{Lang}\Text\_AutoGeneratedTranslations.txt SubstitutionFileTranslation\{Lang}\Text\_Substitutions.txt FallbackCultureen EnableTranslationScopingFalse [Behaviour] MaxCharactersPerTranslation150 EnableBatchingTrue UseStaticTranslationsTrueDirectoryOutputFile定义了翻译文件存放的路径和自动生成翻译的存储文件。{Lang}是占位符会自动替换为Language设置的值。所有放在Directory下的.txt文件都会被加载为翻译词典OutputFile是插件自动记录未翻译文本并生成机翻结果的地方。手动翻译的精髓就在于编辑这个文件。SubstitutionFile替换文件。你可以在这里定义一些简单的文本替换规则在文本发送给翻译服务之前生效。例如你可以把游戏里经常被误译的角色名“リン”直接替换为“Rin”避免翻译API将其翻成“林”或“磷”。MaxCharactersPerTranslation单次翻译请求的最大字符数。这是一个关键的安全和性能设置。在线翻译API通常有单次请求的长度限制。设置过大如超过1000可能导致翻译失败或被API拒绝。社区规范强烈建议在公开发布的任何整合包中此值不得大于400以避免对翻译服务造成过大压力。EnableBatching启用批处理。当游戏短时间内产生大量短文本时如对话逐句显示插件会尝试将它们合并成一个请求发送显著减少API调用次数提升翻译速度和稳定性。UseStaticTranslations启用内置的静态词典。插件内置了一个小型英日词典对于某些常见术语尤其是ACG相关词汇可以提供更准确的翻译减少对在线API的依赖。3.3 高级功能UI重排、字体与正则表达式当翻译后的文本长度远超原文时如英文译成中文通常会更短但日文译成英文或中文可能会变长UI可能会出现文字溢出、重叠等问题。[Behaviour]中的UI重排和字体覆盖功能就是为了解决这个问题。[Behaviour] EnableUIResizingTrue ForceUIResizingFalse OverrideFontTextMeshPro FallbackFontTextMeshProFonts Materials/LiberationSans SDFEnableUIResizing自动尝试调整Text组件的HorizontalOverflow和VerticalOverflow属性让长文本可以换行或溢出显示而不是被截断。这是解决文字显示不全的第一道防线。OverrideFontTextMeshPro/FallbackFontTextMeshPro字体问题是中文翻译中最常见的“拦路虎”。许多游戏的默认字体不包含中文字符集导致翻译出来的中文显示为“口口口”或直接不显示。OverrideFontTextMeshPro用于强制替换所有TextMeshPro组件的字体。你可以指定一个系统中已安装的字体名如Arial或者一个打包好的TMP字体AssetBundle的路径。更常用的是FallbackFontTextMeshPro它为TMP字体添加一个后备字体当主字体缺少某个字符时会自动尝试从后备字体中寻找。插件发布页通常提供一些预制的包含中文的TMP字体AssetBundle。正则表达式Regex的威力 对于结构化的文本如物品名称“生命药水 x5”直接翻译整个字符串效果很差。插件支持在翻译文件中使用正则表达式进行匹配和替换。; 在 Translation\zh-CN\Text\MyRegex.txt 中 r:^(\w) Potion x([0-9])$$1药水 x$2 sr:^([0-9]{2}) ([\S\s])$$1 $2标准正则 (r:): 直接匹配并替换整个文本。上面例子会将“Health Potion x5”匹配并将$1替换为“Health”$2替换为“5”最终输出“Health药水 x5”。这需要你为每种药水都写一条规则。分割器正则 (sr:):这是更强大的功能。它先将文本按规则分割成多个部分分别查询翻译最后再组合。例如游戏可能显示“01 シンプルリング”、“02 シンプルリング”。有了分割器正则sr:^([0-9]{2}) ([\S\s])$$1 $2插件会先将文本分割成“01”和“シンプルリング”然后只为“シンプルリング”查询翻译结果为“Simple Ring”最后组合成“01 Simple Ring”。你只需要一条基础翻译“シンプルリングSimple Ring”就能处理所有带数字前缀的变体极大地减少了翻译文件的工作量。4. 实战操作流程从零开始为游戏添加自动翻译理论讲得再多不如动手操作一遍。下面我将以一名“进阶玩家”的身份演示如何为一款未知的Unity游戏假设为MyGame.exe配置XUnity.AutoTranslator目标是实现日文到简体中文的实时翻译。4.1 环境准备与插件安装确定游戏运行环境首先确认游戏是Mono还是IL2CPP脚本后端。通常可以在游戏目录寻找UnityPlayer.dll和GameAssembly.dllIL2CPP或Mono相关文件夹。XUnity.AutoTranslator对两者都支持但IL2CPP下某些功能如IMGUI翻译可能受限。安装BepInEx前往BepInEx的GitHub发布页下载与游戏架构x86/x64对应的版本。将压缩包内所有文件解压到游戏根目录即MyGame.exe所在目录。安装XUnity.AutoTranslator前往XUnity.AutoTranslator的GitHub发布页下载对应BepInEx 5.x的版本如XUnity.AutoTranslator-BepInEx-5.x.x.x.zip。将其中的plugins文件夹内容解压到游戏目录的BepInEx\plugins文件夹下。最终目录结构应类似于MyGame/ ├── MyGame.exe ├── UnityPlayer.dll ├── BepInEx/ │ ├── core/ │ ├── plugins/ │ │ └── XUnity.AutoTranslator/ │ │ ├── AutoTranslator.dll │ │ ├── XUnity.Common.dll │ │ └── ... │ └── config/ │ └── AutoTranslatorConfig.ini (首次运行后生成) └── ... (其他游戏文件)首次运行与基础配置启动游戏。如果安装成功游戏启动时BepInEx的控制台窗口如果已启用会显示插件加载日志。运行几分钟后退出游戏。此时打开BepInEx\config\AutoTranslatorConfig.ini进行最基础的修改[General] Languagezh-CN [Service] EndpointGoogleTranslate ; 先使用免费端点测试 [Behaviour] MaxCharactersPerTranslation400 ; 设置为安全值 EnableBatchingTrue4.2 配置翻译服务与处理字体问题测试翻译重新启动游戏进入有文本的地方。按默认快捷键Alt0可以打开翻译器状态窗口确认当前语言和端点。如果一切正常游戏内的日文文本应该会逐渐被替换成中文可能有几秒延迟。如果翻译没有出现检查BepInEx的日志文件BepInEx\LogOutput.log是否有错误信息常见问题包括网络连接失败或游戏路径包含非ASCII字符如中文。配置更稳定的翻译端点可选但推荐如果GoogleTranslate不稳定可以申请百度翻译开放平台的免费API每月有一定免费字符额度。获得App ID和密钥后修改配置[Service] EndpointBaiduTranslate [Baidu] BaiduAppId你的AppID BaiduAppSecret你的密钥解决字体显示问题如果翻译后的中文显示为方块或问号说明游戏字体缺失中文字形。我们需要为TextMeshPro添加后备字体。方案A使用内置资源许多Unity游戏内置了LiberationSans SDF字体它支持基本的中文。在配置中设置[Behaviour] FallbackFontTextMeshProFonts Materials/LiberationSans SDF方案B使用外部字体AssetBundle如果方案A无效需要从社区如sorrowmoil-MoeFont-for-XUnity.AutoTranslator仓库下载预制的TMP中文字体AssetBundle一个.unity3d文件将其放入游戏根目录然后在配置中指定文件名不含扩展名[Behaviour] FallbackFontTextMeshProMyChineseFontBundle重启游戏中文应该能正常显示了。4.3 管理翻译文件与进行手动校对自动翻译只是第一步机翻质量往往需要人工干预。这是提升体验的关键。定位翻译文件游戏运行并翻译过一些文本后在BepInEx\translation\zh-CN\Text目录下会生成_AutoGeneratedTranslations.txt文件。这个文件记录了插件捕获到的所有原文及其机翻结果。编辑翻译文件用文本编辑器打开_AutoGeneratedTranslations.txt。你会看到类似这样的行こんにちは你好 これはテストです这是一个测试等号左边是游戏中的原文右边是机翻结果。你可以直接修改等号右边的文本将其改为更准确、更符合语境的翻译。例如将生硬的“这是一个测试”改为“这是一条测试消息”。保存文件后在游戏中按AltR快捷键即可即时重载翻译文件看到修改后的效果。这是迭代优化翻译的核心工作流。创建独立的翻译文件不建议直接在_AutoGeneratedTranslations.txt中大量编辑因为该文件会被插件不断追加新内容。更好的做法是将校对好的翻译行复制出来粘贴到一个新建的.txt文件中例如MyManualTranslations.txt并放在同一个Text文件夹下。插件会加载所有.txt文件并且手动文件的优先级高于自动生成的文件。这样即使自动文件被重置或更新你的精翻内容也不会丢失。使用替换文件Substitutions对于游戏中反复出现、但机翻总是出错的专有名词如角色名、技能名、地名可以在_Substitutions.txt中定义替换规则。例如リンRin フィリアPhilia这样在文本发送给翻译API之前“リン”就会被替换成“Rin”避免了被翻译成其他奇怪词汇。4.4 启用纹理图片翻译对于UI图标、标题Logo等图片资源中的文字文本翻译无能为力。XUnity.AutoTranslator提供了纹理替换功能。启用纹理相关功能在配置文件中找到[Texture]段落进行如下设置[Texture] EnableTextureTranslationTrue EnableTextureDumpingTrue EnableTextureScanOnSceneLoadTrue TextureDirectoryTranslation\Texture TextureHashGenerationStrategyFromImageName CacheTexturesInMemoryTrueEnableTextureDumpingTrue这个设置会让插件将游戏中的所有纹理图片导出到TextureDirectory指定的目录。这是一个调试功能仅在你自己准备翻译图片时启用。在制作最终发布给别人的整合包时必须将其设为False。EnableTextureScanOnSceneLoadTrue在场景加载时扫描纹理有助于找到更多可替换的UI图片。导出与编辑图片启动游戏并浏览各个界面。插件会将检测到的纹理图片以文件名 [哈希值].png的格式导出到BepInEx\translation\Texture目录。你可以用图片编辑软件如Photoshop、GIMP打开这些PNG文件将其中的外文文字修改为目标语言。替换图片编辑完成后保持文件名包括哈希值完全不变将图片放回原目录。将EnableTextureDumping设为False然后重启游戏。插件就会加载你修改后的图片替换游戏内的原始纹理。重要警告纹理替换功能性能开销较大尤其是启用EnableTextureDumping和EnableTextureScanOnSceneLoad时。在发布整合包前务必确认已关闭所有调试选项Dumping, Toggling, LoadUnmodifiedTextures等并将TextureHashGenerationStrategy优先设置为FromImageName以提升性能。5. 疑难杂症排查与进阶技巧即使按照步骤操作也难免会遇到各种问题。下面是我在长期使用中总结的一些常见“坑点”和解决方案。5.1 翻译不生效或显示异常问题游戏启动后文本毫无变化按Alt0也弹不出窗口。排查首先检查BepInEx\LogOutput.log。如果根本没有BepInEx的日志说明BepInEx安装失败可能是游戏版本特殊或防篡改机制。如果日志中有XUnity.AutoTranslator加载失败的错误可能是插件版本与BepInEx不兼容或缺少依赖如XUnity.Common.dll。解决确保使用了正确版本的BepInEx和AutoTranslator。对于某些使用了MonoMod的特殊游戏可能需要使用插件包中附带了MonoMod运行时的版本如BepInEx 5.x整合包通常已包含。问题翻译窗口能弹出端点显示正常但游戏内文本仍是原文。排查检查配置文件中的Language是否设置正确。查看日志中是否有大量的翻译失败错误如网络超时、API限额已满。解决切换到另一个翻译端点测试如从GoogleTranslate换到BaiduTranslate。如果使用API确认密钥填写无误且未过期。临时关闭防火墙或安全软件排除网络干扰。问题中文显示为“口口口”或空白。排查这是典型的字体缺失问题。解决按照前文所述正确配置FallbackFontTextMeshPro。如果使用了自定义字体AssetBundle确保其与游戏使用的TextMeshPro版本兼容。可以尝试在游戏中按F12如果安装了UnityExplorer等调试插件检查TextMeshPro组件的字体信息确认后备字体是否加载成功。问题翻译后游戏逻辑出错或崩溃例如某些选项无法点击。排查有些游戏会通过检查屏幕上显示的文本来决定执行哪段逻辑代码。翻译改变了文本导致游戏逻辑判断失误。解决在配置文件中尝试启用TextGetterCompatibilityModeTrue。这个模式会“欺骗”游戏让它认为显示的仍是原始文本。5.2 性能优化与高级配置翻译延迟高游戏内文本出现后要等好几秒才翻译。优化确保[Behaviour]中EnableBatchingTrue。适当增加MaxCharactersPerTranslation但不要超过400减少请求次数。如果使用免费端点延迟是固有的考虑使用付费API或离线翻译引擎需自行实现ITranslateEndpoint。内存占用过高启用了纹理翻译后游戏内存使用量激增。优化将[Texture]下的CacheTexturesInMemory设置为False。这会降低纹理加载速度但能节省内存。仔细检查导出的纹理图片删除所有你不打算修改的图片文件减少插件需要扫描和管理的文件数量。翻译文件混乱_AutoGeneratedTranslations.txt文件越来越大包含大量重复或无效条目。管理定期清理这个文件。可以将其备份后清空重新进入游戏让插件生成新的记录这样能过滤掉很多一次性或错误的文本。将确认无误的精翻内容迁移到独立的手动翻译文件中。为特定场景或EXE配置翻译如果你在为一个包含多个可执行程序如本体、DLC、特典的游戏制作翻译或者某个翻译只适用于游戏中的某个迷你游戏场景可以使用**翻译作用域Scoping**功能。方法在配置中启用EnableTranslationScopingTrue。然后在你的手动翻译文件不能是_AutoGeneratedTranslations.txt中使用指令。例如#set exe Game_DLC.exe 特定DLC的文本DLC Specific Text #unset exe或者使用场景ID可通过游戏内按CtrlAltNum7查看#set level 5 只有场景5才有的文本Text only for level 5 #unset level5.3 开发者与模组作者进阶如果你是一名模组作者希望自己的模组UI不被AutoTranslator干扰或者想为其添加专属翻译插件也提供了API。让插件忽略你的UI对于基于GameObject的UI只需将包含Text组件的GameObject名称中包含字符串XUAIGNORE插件就会跳过它。如果命名为XUAIGNORETREE则该节点下所有子对象的文本都不会被翻译。为你的模组提供专属翻译在翻译目录下创建Plugins文件夹再在里面为你的模组DLL创建一个同名文件夹不含.dll扩展名。将翻译文件放入其中。你还可以在翻译文件中添加#enable fallback指令允许插件在找不到专属翻译时回退到通用的自动翻译。实现自定义翻译端点如果你有私有的翻译服务或离线引擎可以参考官方文档实现ITranslateEndpoint接口。核心就是实现Initialize和Translate方法将context.UntranslatedText发送到你的服务并将结果通过context.Complete(translatedText)返回。编译成DLL后放入Translators目录即可在插件端点列表中选择。最后关于IL2CPP的支持需要特别说明虽然插件支持IL2CPP但某些功能如TextGetterCompatibilityMode、IMGUI翻译可能不可用或存在问题。如果遇到文本钩子失效的情况可以尝试使用社区提供的AutoTranslator.IL2CPP.BruteForceFix辅助插件来强制刷新文本组件。IL2CPP下的调试更加困难遇到问题多查阅社区讨论和Issues往往是更快的解决途径。