Unity游戏实时翻译插件XUnity Auto Translator实战指南
1. 项目概述为什么你需要XUnity Auto Translator如果你是一名Unity游戏的玩家尤其是经常接触那些由独立开发者或小型团队制作的、尚未推出官方中文版的游戏那么你一定对满屏的英文、日文或其他语言感到头疼。手动替换游戏内的文本文件那太麻烦了而且容易出错。直接等汉化组很多小众游戏可能永远等不到。这时候一个能实时、自动翻译游戏内文本的工具就显得至关重要。XUnity Auto Translator以下简称XUAT就是这样一个“神器”。它不是一个简单的文本替换工具而是一个功能强大的Unity游戏翻译插件。它的核心原理是在游戏运行时通过Hook挂钩Unity引擎的文本渲染流程拦截即将显示在屏幕上的文本将其发送到你指定的翻译服务如谷歌翻译、百度翻译等然后将翻译结果实时替换回游戏界面。整个过程对游戏本身几乎无感你只需要安装配置好就能立刻享受“生肉变熟肉”的便利。我接触这个插件已经有好几年了从早期的版本用到现在看着它从一个基础的文字替换工具发展到现在支持纹理替换、正则表达式、资源重定向等高级功能的庞然大物。它几乎成了我玩任何Unity游戏的标配前置工具。今天我就把我这些年积累的实战经验浓缩成五个核心步骤带你从零开始彻底掌握XUAT让你玩转任何Unity游戏再无语言障碍。2. 核心思路拆解XUAT是如何工作的在动手之前我们必须理解XUAT的运作机制这样才能在遇到问题时知道从哪里下手。你可以把它想象成一个安装在游戏和屏幕之间的“同声传译员”。2.1 核心工作流程当游戏调用Unity的UI系统如UGUI的Text组件、TextMeshPro甚至是古老的NGUI、IMGUI来显示一段文本时XUAT的Hook会介入。它首先会检查这段文本是否在本地翻译缓存文件中通常是_AutoGeneratedTranslations.txt。如果在直接使用缓存结果速度极快。如果不在它会根据你的配置将这段文本发送到配置好的在线翻译API如Google Translate获取翻译结果并同时将原文和译文记录到缓存文件中供下次使用。最后它通过Unity的API将游戏原本要显示的文本替换成翻译后的文本。这个过程有几个关键点非侵入式它不修改游戏原始文件所有翻译数据都存放在游戏目录下的独立文件夹中。卸载插件只需删除对应文件游戏即刻恢复原状。缓存优先首次翻译某句文本后结果会被保存。下次游戏再显示相同文本时直接读取本地缓存无需再次联网既快又省流量也减轻了翻译API的负担。高度可配置从翻译服务、字体、UI缩放、正则处理到资源替换几乎所有环节都可以通过配置文件Config.ini进行精细调整。2.2 三大核心模块理解了流程我们再拆解它的三大功能模块这对应着三种不同层级的翻译需求文本翻译核心功能这是最基本也是最常用的功能即实时翻译游戏内的所有文字。XUAT支持多种UI框架并能智能处理空格、换行符确保翻译准确插入。纹理图片翻译对于游戏中的图片文字比如UI图标上的文字、剧情CG中的字幕纯文本翻译无能为力。XUAT的纹理翻译功能可以dump导出游戏内的图片资源让你用修图软件替换其中的文字后再让插件在游戏运行时加载你修改后的图片。这需要一定的动手能力但能实现近乎完美的全游戏汉化。资源重定向高级功能这是为高阶用户和Mod开发者准备的核武器。它允许你在更深层次拦截和替换游戏加载的任何资源如TextAsset、音频、预制体等不仅仅是运行时文本。这意味着你可以直接提供一套完整的、修改过的游戏资源文件如汉化好的脚本文件让游戏直接加载它们实现最彻底、性能损耗最低的本地化。3. 实战五步走从安装到精通理论说再多不如动手做一遍。下面这五个步骤是我总结的最高效的XUAT配置流程。3.1 第一步环境准备与插件安装XUAT本身是一个插件它需要依赖一个“插件加载器”才能注入到Unity游戏中。最常见的是BepInEx。确认游戏框架首先你需要确定你的Unity游戏使用什么框架。绝大多数现代Unity游戏都使用Mono或IL2CPP作为脚本后端。你可以通过游戏目录下是否存在GameName_Data/Managed/文件夹来判断如果存在通常是Mono如果存在GameName_Data/il2cpp_data等则是IL2CPP。XUAT对两者都支持但IL2CPP的支持度稍弱例如IMGUI翻译可能不支持。安装BepInEx前往BepInEx的GitHub发布页下载对应你游戏架构x86或x64的版本。将压缩包内的所有文件解压到你的游戏根目录即GameName.exe所在的文件夹。首次运行游戏BepInEx会自动生成必要的文件夹结构BepInEx/plugins,BepInEx/config等。安装XUnity Auto Translator前往XUAT的GitHub发布页根据你的游戏框架和BepInEx版本下载对应的包。对于BepInEx 5.x通常选择XUnity.AutoTranslator-BepInEx-5.x-{VERSION}.zip。解压后你会看到BepInEx文件夹。将其合并到游戏根目录的BepInEx文件夹中。确保XUnity.AutoTranslator和XUnity.ResourceRedirector这两个插件出现在BepInEx/plugins目录下。首次运行与确认再次启动游戏。如果安装成功游戏启动时在命令行窗口或游戏内按F1/F2取决于BepInEx配置应该能看到XUAT的加载日志。进入游戏后按Alt0默认热键应该能呼出XUAT的配置面板。实操心得如果游戏启动崩溃首先检查BepInEx版本是否与游戏兼容32位/64位。其次检查XUAT的依赖项如XUnity.Common.dll是否完整。IL2CPP游戏可能需要额外的兼容性插件如AutoTranslator.IL2CPP.BruteForceFix。3.2 第二步基础配置与翻译服务设置安装成功后我们需要进行最关键的配置——选择翻译引擎。配置文件位于BepInEx/config/AutoTranslatorConfig.ini。用记事本或任何文本编辑器打开它。选择翻译终端Endpoint找到[General]章节下的Endpoint这一行。这是核心设置。XUAT内置了多种翻译服务GoogleTranslate: 谷歌翻译免费需网络国内可能需要特殊网络环境。BaiduTranslate: 百度翻译需要申请App ID和密钥有免费额度。DeepLTranslate: DeepL翻译质量高但免费版有限制。Empty: 空即禁用自动翻译仅使用本地翻译文件。将Endpoint设置为你想要的服务例如EndpointGoogleTranslate。配置翻译服务密钥如需如果你选择了需要认证的服务如百度、DeepL需要在配置文件下方对应的章节填写密钥。例如选择百度翻译你需要去百度翻译开放平台注册创建应用获取BaiduAppId和BaiduAppSecret然后填写到[Baidu]章节下。设置源语言与目标语言在[General]章节找到Language和FromLanguage。Language: 目标语言即你想翻译成的语言。例如zh-CN简体中文、ja日语。FromLanguage: 源语言即游戏原本的语言。如果你不确定可以设置为auto自动检测但设置准确的语言如ja对于日文游戏能提高翻译准确率。关键行为配置EnableTranslationTrue: 确保翻译功能是开启的。MaxCharactersPerTranslation400: 单次翻译的最大字符数。切勿超过1000也绝对不要在分享你的翻译补丁时设置大于400的值以免滥用翻译API。EnableBatchingTrue: 启用请求批处理将多个短句合并后发送能显著减少API调用次数。一个基础的[General]配置示例如下[General] Languagezh-CN FromLanguageja EndpointGoogleTranslate EnableTranslationTrue MaxCharactersPerTranslation400 EnableBatchingTrue3.3 第三步处理字体与UI显示问题翻译成中文后最常见的问题是“口口口”乱码这是因为游戏原版字体不包含中文字符集。XUAT提供了字体覆盖功能。字体覆盖OverrideFont在[Behaviour]章节找到OverrideFont。你可以在这里指定一个字体文件或系统字体名。使用系统字体直接填写字体名称如Microsoft YaHei微软雅黑。前提是该字体已安装在你的系统上且游戏使用的TextMeshPro版本在3.2.0以上。使用AssetBundle字体这是更可靠的方法。你需要一个为游戏打包好的、包含中文字体的AssetBundle文件。网上有一些社区制作好的通用字体包如sorrowmoil-MoeFont-for-XUnity.AutoTranslator项目中的字体。下载后将.bundle或.assets文件放在游戏根目录然后在配置中填写文件名不含路径如OverrideFontTextMeshProzho_cn.bundle。UI自动重设大小EnableUIResizing中文通常比英文/日文更紧凑但有时也会更长导致文本显示不全。开启EnableUIResizingTrue可以让XUAT尝试自动调整文本框的尺寸和换行设置来容纳翻译后的文本。如果自动调整不理想可以尝试更激进的ForceUIResizingTrue。手动UI字体大小调整对于某些顽固的UI元素自动调整可能无效。XUAT支持通过resizer.txt文件进行精确控制。你需要在Translation\{Lang}\Text目录下创建resizer.txt文件并按照组件路径命令的格式编写规则。例如TitleScreen/Canvas/Panel/TitleTextChangeFontSizeByPercentage(0.8)这条规则会将TitleText路径下所有文本组件的字体大小调整为原来的80%。要获取准确的组件路径你需要开启EnableTextPathLoggingTrue然后在游戏中触发文本显示查看XUAT的日志输出。3.4 第四步翻译文件管理与高级技巧XUAT的强大之处在于它对翻译文件的精细管理。翻译文件的生成与位置所有翻译文件都存放在BepInEx/Translation\{Lang}/Text/目录下。其中_AutoGeneratedTranslations.txt是插件自动生成和更新的缓存文件。不要直接编辑这个文件因为你的修改可能会被插件覆盖。创建手动翻译文件正确的做法是将_AutoGeneratedTranslations.txt中翻译不满意或错误的条目复制出来粘贴到一个新的.txt文件中例如MyManualTranslations.txt并在这个新文件里进行修改。XUAT会读取Text目录下所有的.txt文件并且手动文件的优先级高于自动生成的文件。这样既能保留自动翻译的便利又能进行人工校对和优化。使用正则表达式Regex游戏文本有时会动态拼接比如“你获得了 10 金币”。如果“金币”这个词被单独翻译了但数字是变量自动翻译就会失效。这时可以用正则表达式。在手动翻译文件中你可以添加这样的行r:你获得了 (\d) 金币You got $1 gold coins r:^(.) LV\.(\d)$$1 Lv.$2第一行匹配“你获得了 X 金币”并保留数字第二行匹配“XXX LV.XX”这种格式并保留名称和等级。正则表达式以r:开头。使用分割器正则表达式Splitter Regex对于更复杂的情况比如[ATK10][DEF5] 超级药水你可以用sr:splitter regex先将字符串按模式分割成[ATK10]、[DEF5]、超级药水三部分然后分别对超级药水进行翻译最后再组合回去。这需要对正则表达式有较深的理解。翻译作用域Scoping你可以通过指令将翻译限制在特定场景或游戏可执行文件下避免翻译冲突。在翻译文件顶部添加#set level 5 はい是 #unset level这表示“はい是”这个翻译只会在场景ID为5时生效。场景ID可以通过游戏内按CtrlAltNum7查看。3.5 第五步纹理翻译与资源重定向高阶应用当文本翻译无法满足需求时如图片UI、CG字幕就需要用到更高级的功能。启用纹理翻译在Config.ini中找到[Texture]章节。设置EnableTextureTranslationTrue。设置EnableTextureDumpingTrue。重要仅在你自己导出图片时开启制作完翻译补丁后务必将其设为False再分发运行游戏XUAT会将游戏内可替换的纹理图片导出到BepInEx/Translation\{Lang}\Texture目录下文件名会包含哈希值用于标识。编辑与替换纹理用图像处理软件如Photoshop、GIMP打开导出的图片将其中的外文修改为中文务必保持图片尺寸和文件名中的哈希值不变然后保存。重新打包与测试关闭纹理导出EnableTextureDumpingFalse确保EnableTextureTranslationTrue重新运行游戏。如果一切正常修改后的图片就会替换游戏内的原图。理解资源重定向纹理翻译本质上是资源重定向功能的一个应用。XUnity.ResourceRedirector这个库允许开发者编写更复杂的Mod直接替换游戏加载的脚本文件TextAsset、音频等。对于普通玩家主要用到的是EnableTextAssetRedirectorTrue。开启后游戏加载的所有文本资源如.json,.txt等配置文件都会被导出你可以直接修改这些文件来实现更底层的汉化比如修改物品描述文件修改后的文件会被游戏优先加载。深度解析纹理哈希策略配置文件中的TextureHashGenerationStrategy选项至关重要。它决定了如何识别一张图片。FromImageName基于游戏内部资源名生成哈希。性能最好是分发补丁时的推荐选项。但有些图片可能没有资源名。FromImageData基于图片像素数据生成哈希。最准确但导出和运行时都需要读取所有图片数据性能开销大仅当FromImageName无效时使用。FromImageNameAndScene结合资源名和场景名。用于解决资源名不唯一的情况。核心原则制作并分享你的纹理翻译补丁时永远使用FromImageName并确保删除了所有未翻译的原始图片文件以减小补丁体积并避免加载错误。4. 疑难杂症排查与性能优化即使按照步骤操作也难免会遇到问题。下面是我踩过无数坑后总结的常见问题速查表。问题现象可能原因解决方案游戏启动崩溃或插件未加载1. BepInEx版本与游戏不兼容x86/x64。2. 游戏为IL2CPP且未使用兼容性插件。3. 插件文件缺失或放错位置。1. 确认游戏位数下载对应BepInEx。2. 为IL2CPP游戏尝试安装BruteForceFix插件。3. 检查BepInEx/plugins目录下是否有XUAT相关dll。按Alt0无反应无翻译效果1. 热键冲突或被游戏屏蔽。2. 翻译功能未启用或Endpoint为空。3. 游戏UI框架特殊如自定义渲染。1. 尝试AltT切换翻译开关看是否有提示音。2. 检查Config.ini中EnableTranslation和Endpoint设置。3. 尝试开启EnableIMGUITrue如果游戏用IMGUI。对于NGUI/UGUI确保EnableUIResizing已尝试。翻译结果为“口口口”乱码游戏字体不支持目标语言字符。1. 配置OverrideFont或OverrideFontTextMeshPro指向一个支持目标语言的字体文件AssetBundle。2. 尝试使用FallbackFontTextMeshPro添加后备字体。翻译后文本显示不全、重叠或超出框外UI文本框尺寸或溢出设置不适应翻译后文本。1. 启用EnableUIResizingTrue或ForceUIResizingTrue。2. 使用resizer.txt文件对特定UI路径进行手动字体大小和溢出模式调整。翻译API频繁报错或翻译慢1. 网络连接问题。2. API密钥无效或额度用尽。3. 未开启批处理短句过多。1. 检查网络对于某些服务可能需要特定的网络环境。2. 检查并更新API密钥。3. 确保EnableBatchingTrue并适当调整MaxCharactersPerTranslation不超过400。部分文本未被翻译1. 文本是图片纹理。2. 文本由特殊插件生成被XUAT忽略。3. 文本包含不可翻译字符或格式。1. 启用纹理翻译功能。2. 检查游戏是否有其他Mod冲突或尝试在配置中调整IgnoreTextStartingWith。3. 检查MaxCharactersPerTranslation是否设置过小过滤了长文本。开启纹理翻译后游戏变卡或内存占用高1. 开启了EnableTextureDumping导出或EnableTextureScanOnSceneLoad场景扫描。2.CacheTexturesInMemoryTrue且纹理过多。3. 使用了FromImageData哈希策略。1.仅在需要导出图片时开启Dumping和Scan完成后立即关闭。2. 如果内存吃紧可尝试CacheTexturesInMemoryFalse但可能会增加加载卡顿。3.分发补丁时务必使用FromImageName并清理未修改的图片。自动生成的翻译文件混乱包含大量无意义字符游戏输出了大量非对话文本如调试信息、代码变量名。1. 设置OutputUntranslatableTextFalse默认。2. 在[Behaviour]中配置IgnoreTextStartingWith过滤掉以某些字符如_,$开头的文本。性能优化黄金法则缓存即王道首次游玩时耐心等待自动翻译生成缓存文件。之后游玩绝大部分翻译都来自本地缓存体验丝滑。纹理翻译慎用这是一个重量级功能。只在必要时开启并严格遵守“导出时开游玩时关”的原则。分发补丁前确认EnableTextureDumping、EnableTextureToggling、LoadUnmodifiedTextures、DetectDuplicateTextureNames这几个选项全部为False。正则表达式少而精滥用正则表达式会显著增加文本匹配时的性能开销。只在必要时使用并尽量让模式具体。关闭调试日志在稳定使用后确保[Debug]章节下的EnableLogFalse避免不必要的磁盘写入和性能损耗。5. 从使用者到贡献者高级定制与开发当你熟练使用XUAT后你可能会不满足于仅仅使用它。无论是想分享自己的翻译补丁还是想为特定游戏开发深度汉化Mod以下内容将为你打开新世界的大门。5.1 制作并分享你的翻译补丁当你为某个游戏精心打磨了一套翻译包括文本和纹理你可能会想分享给其他玩家。请遵循以下规范清理缓存文件将BepInEx/Translation/{Lang}/Text/目录下的_AutoGeneratedTranslations.txt文件用文本编辑器打开删除其中明显错误、无意义或过于个人化的翻译条目。保留那些准确、通用的翻译。打包将整理好的Translation文件夹整个打包。确保里面没有包含你的个人API密钥的配置文件。提供清晰的安装说明告诉用户只需将Translation文件夹解压到游戏的BepInEx目录下即可。提醒他们可能需要根据自己情况调整Config.ini中的语言和字体设置。重要禁令绝对不要分享带有EnableTextureDumpingTrue或配置了非内置翻译API如你自己的Google API密钥的Config.ini文件。这会导致其他用户无意中向API发送大量请求可能导致你的API密钥被封禁也违背了插件原作者关于再分发的建议。5.2 为其他Mod提供翻译支持如果你是一个Mod开发者或者你想为你喜欢的Mod制作汉化XUAT提供了完美的支持。插件特定翻译在Translation/{Lang}/Text/目录下创建一个名为Plugins的文件夹。在这个文件夹里为你想要翻译的Mod创建一个子文件夹文件夹名必须与该Mod的主dll文件名不含扩展名完全一致。例如一个叫AwesomeMod.dll的Mod其翻译文件夹路径应为Translation/zh-CN/Text/Plugins/AwesomeMod/。在这个文件夹里放置你的翻译.txt文件即可。XUAT会优先使用这里的翻译。在Mod代码中集成如果你是Mod作者你甚至可以将翻译文件嵌入到你的Mod.dll中并通过XUAT提供的TranslationRegistryAPI在运行时注册它们实现开箱即用的汉化。这需要一定的C#编程能力但能提供最无缝的体验。5.3 开发自定义翻译器或资源重定向器这是最高阶的应用。XUAT拥有开放的架构允许开发者为其添加新的在线翻译服务支持或者利用其底层的资源重定向功能实现更复杂的游戏修改。实现ITranslateEndpoint接口如果你想接入一个XUAT尚未支持的翻译API例如国内的火山翻译、腾讯翻译君你可以创建一个新的类库项目引用XUnity.AutoTranslator.Plugin.Core.dll实现ITranslateEndpoint接口。你需要处理API调用、错误处理和结果解析。完成后将编译好的DLL放入游戏的BepInEx/translators目录即可在XUAT的配置中选择你的新翻译服务。使用Resource Redirector APIXUnity.ResourceRedirector.dll提供了一个强大的钩子Hook系统允许你在游戏加载资源AssetBundle, Resources的瞬间拦截并修改它们。这不仅仅是翻译文本你可以替换模型、音效、整个UI预制体。例如你可以写一个插件在游戏加载日文语音文件时将其重定向到你准备好的中文语音文件。这需要对Unity的资产加载流程和C#编程有深入理解。从我个人的经验来看XUAT不仅仅是一个翻译工具它更是一个通往Unity游戏Modding世界的桥梁。通过它你不仅能打破语言壁垒更能深入理解游戏是如何构建和运行的。从最初磕磕绊绊地配置字体解决乱码到后来为心爱的游戏制作包含图片翻译的完整汉化包再到尝试为某个小游戏写一个简单的资源替换Mod每一步都充满了挑战和成就感。记住社区是最大的宝藏遇到棘手的问题时不妨去GitHub的Issues页面或者相关的游戏Mod论坛看看很可能已经有人提供了解决方案。