1. 项目概述为什么你需要XUnity.AutoTranslator如果你是一个喜欢玩各种独立游戏、视觉小说或者日系RPG的玩家肯定遇到过语言不通的烦恼。游戏本身质量很高但苦于没有官方中文只能对着满屏的日文或英文干瞪眼或者依赖社区汉化组遥遥无期的等待。又或者你是一个游戏开发者想要快速了解海外同行的作品语言成了第一道门槛。这时候一个能实时翻译游戏内文本的工具就成了刚需。而XUnity.AutoTranslator正是为解决这个问题而生的神器。它不是一个简单的屏幕OCR翻译工具而是一个直接注入到Unity游戏进程中的插件。简单来说它能在游戏运行时拦截游戏引擎Unity渲染文本的底层调用将原始文本替换成你指定的翻译结果。这意味着翻译是“无缝”的——字体、样式、显示位置都和原版保持一致体验上几乎就像游戏原生支持了你的语言。我接触这个插件已经好几年了从早期的版本一路用过来看着它从一个功能相对简单的文本替换工具进化成如今支持纹理替换、正则表达式、资源重定向等高级功能的庞然大物。它极大地拓宽了玩家的游戏库让无数“生肉”游戏变得可玩。今天我就以一名老玩家的视角带你用最核心的三步从零开始掌握这个工具实现Unity游戏的实时翻译。2. 核心三步走从安装到实战的完整流程很多人看到插件的配置文件里密密麻麻的参数就头大其实核心的使用流程可以高度概括为三个步骤环境准备与安装、基础配置与翻译引擎设置、启动游戏与调优。只要跟着这三步走90%的Unity游戏都能顺利吃上“熟肉”。2.1 第一步环境准备与插件安装这一步的目标是让游戏能够加载XUnity.AutoTranslator插件。由于Unity游戏本身不提供Mod加载功能我们需要一个“中介”——插件加载器。最常见的选择是BepInEx。1. 确定游戏使用的Unity版本和运行环境首先你需要知道你的游戏是基于哪个Unity版本构建的以及它是Mono运行时还是IL2CPP运行时。一个简单的判断方法是查看游戏根目录下是否有GameName_Data/Managed/文件夹。如果有通常是Mono如果只有GameName_Data/il2cpp_data/则是IL2CPP。IL2CPP的游戏需要额外步骤我们稍后再说。2. 下载并安装BepInEx前往BepInEx的GitHub发布页下载对应你游戏架构x86或x64的版本。通常下载BepInEx_x64_5.4.xx.x.zip即可。将压缩包内的所有文件解压到游戏根目录即GameName.exe所在的文件夹。首次运行游戏BepInEx会自动生成必要的文件夹结构BepInEx\plugins,BepInEx\config,BepInEx\patchers等。3. 安装XUnity.AutoTranslator前往XUnity.AutoTranslator的GitHub发布页根据你的插件加载器选择对应的版本。对于BepInEx 5请下载XUnity.AutoTranslator-BepInEx-5.x-{VERSION}.zip。解压后你会看到两个核心文件夹BepInEx和Translation。将BepInEx\plugins下的XUnity.AutoTranslator文件夹整个复制到你游戏目录的BepInEx\plugins\下。将Translation文件夹复制到游戏根目录。注意XUnity.ResourceRedirector.dll是AutoTranslator的依赖库负责资源重定向功能如替换图片通常会自动放在正确位置无需手动处理。确保它存在于BepInEx\plugins\XUnity.AutoTranslator或BepInEx\core目录下。4. 针对IL2CPP游戏的额外步骤如果你的游戏是IL2CPP常见于较新的Unity游戏或移动端移植作品标准的BepInEx可能无法直接工作。你需要使用专门为IL2CPP适配的BepInEx版本例如BepInEx-Unity.IL2CPP-win-x64-xxx.zip。安装步骤类似但有时还需要配合AutoTranslator.IL2CPP.BruteForceFix这个辅助插件来增强文本钩子能力将其放入BepInEx\plugins目录即可。实操心得在安装任何Mod前务必备份你的游戏存档。虽然翻译插件一般不会影响存档但防患于未然。如果游戏启动失败或崩溃首先检查BepInEx的日志文件BepInEx\LogOutput.log。里面通常会明确指出是哪个插件或依赖项出了问题。对于Steam游戏建议在Steam库中右键游戏属性在“启动选项”里添加--doorstop-enable true以确保BepInEx正确注入。2.2 第二步基础配置与翻译引擎设置安装完成后首次运行游戏插件会在BepInEx\config\AutoTranslatorConfig.ini生成默认配置文件。这是整个插件的“大脑”我们需要对其进行关键设置。1. 打开并编辑配置文件用记事本或任何文本编辑器打开AutoTranslatorConfig.ini。文件开头几行就是最关键的配置。2. 设置源语言和目标语言[General] Languagezh-CN FromLanguagejaLanguage: 你想要翻译成的语言例如简体中文是zh-CN繁体中文是zh-TW英文是en。FromLanguage: 游戏的原始语言。大多数情况下对于日系游戏设置为ja日语欧美游戏设置为en。插件会根据这个设置来匹配翻译方向。3. 选择并配置翻译端点Endpoint这是核心中的核心决定了插件从哪里获取翻译。找到[Service]部分[Service] EndpointGoogleTranslate插件内置了多个翻译引擎如GoogleTranslate谷歌翻译、BaiduTranslate百度翻译、DeepLTranslateDeepL等。对于免费用户GoogleTranslate通常是首选因为它不需要API密钥且支持的语言对最全。配置谷歌翻译无API密钥这是最简单的方式。只需将Endpoint设置为GoogleTranslate即可。插件会模拟浏览器请求访问谷歌翻译的公共页面。但请注意这种方式可能受网络环境限制且有一定请求频率限制。配置百度翻译需要API密钥更稳定如果你在国内网络环境下百度翻译的稳定性和速度可能更好。你需要注册百度翻译开放平台获取App ID和密钥。将Endpoint改为BaiduTranslate。在配置文件靠后的[Baidu]部分填写你的密钥[Baidu] BaiduAppId你的AppID BaiduAppSecret你的密钥配置DeepL需要API密钥质量高DeepL的翻译质量公认较高尤其对于欧洲语言。你需要注册DeepL API有免费额度。将Endpoint改为DeepLLegitimate。在[DeepLLegitimate]部分填写API密钥并设置FreeFalse如果你用的是Pro版API。[DeepLLegitimate] ApiKey你的DeepL API密钥 FreeFalse4. 其他关键基础配置[Behaviour] MaxCharactersPerTranslation150 EnableTranslationScopingTrueMaxCharactersPerTranslation: 单次翻译的最大字符数。强烈建议设置为150-200之间。设置太高如默认的1000会导致向翻译API发送过长的文本可能被拒绝服务或产生糟糕的翻译结果因为上下文断裂。这也是插件作者强调“切勿分发大于400值”的原因。EnableTranslationScoping: 启用翻译作用域。允许你为不同的游戏场景Level或可执行文件设置不同的翻译文件避免翻译冲突建议开启。5. 启用控制台可选用于调试[Debug] EnableConsoleTrue EnableLogTrue将这两项设为True游戏运行时按反引号键通常在ESC下方可以打开控制台查看插件加载、翻译请求等日志信息对于排查问题非常有用。2.3 第三步启动游戏与实时调优完成配置后启动游戏。如果一切正常你应该能看到游戏内的文本逐渐被替换成中文。1. 热键操作插件提供了一系列热键在游戏中直接使用ALT0: 打开翻译端点选择菜单可以快速切换不同的翻译服务如从谷歌切换到百度。ALTT:全局翻译开关。这是最常用的热键可以一键开启或关闭所有文本的实时翻译。如果翻译导致游戏UI错乱或功能异常可以立即关闭。ALTR: 重新加载所有翻译文件。当你手动修改了Translation文件夹下的文本文件后按此键无需重启游戏即可生效。2. 监控与验证首次运行插件会开始拦截游戏文本并通过你配置的端点进行翻译。翻译结果会缓存到Translation\{Lang}\Text\_AutoGeneratedTranslations.txt文件中。你可以打开这个文件查看哪些文本已经被翻译并可以手动修正不满意的翻译。手动修正的翻译优先级高于自动生成。3. 处理字体显示问题翻译成中文后最常见的UI问题是“□□□”这样的豆腐块。这是因为游戏原版字体不包含中文字形。解决方法是在配置文件中启用字体覆盖[Font] OverrideFontTextMeshProFonts Materials/LiberationSans SDF对于使用TextMeshProTMP的现代Unity游戏可以尝试上述配置使用TMP自带的备用字体。如果不行你需要为游戏导入一个包含中文的TMP字体资产包.assetbundle文件并将其路径配置在这里。社区有爱好者制作了通用的中文字体包可以搜索“XUnity AutoTranslator 中文字体”获取。4. 处理UI布局错乱翻译后的文本可能比原文长导致显示不全。插件内置了基础的UI自动调整功能[Behaviour] EnableUIResizingTrue但有时不够用。你可以通过创建resizer.txt文件来手动指定特定UI元素的字体缩放。这需要借助Runtime Unity Editor这类工具来探查游戏内UI元素的完整路径。避坑指南翻译延迟或失败首先检查控制台日志看是否有网络错误或API限额提示。如果使用谷歌翻译且网络不畅可以尝试在配置中设置[Google] ServiceUrl指向一个可用的镜像地址需自行寻找注意合规性。更稳妥的方法是切换到百度翻译或DeepL并配置好API密钥。游戏崩溃或功能异常尝试设置[Behaviour] TextGetterCompatibilityModeTrue。有些游戏会通过检查显示的文本来触发逻辑翻译后文本改变可能导致逻辑错误。此模式会欺骗游戏让它“看到”的还是原始文本。特定文本不想被翻译比如一些代码、变量名或专有名词。可以在配置中设置[Behaviour] IgnoreTextStartingWith例如IgnoreTextStartingWith;{可以忽略以这些字符开头的文本。3. 高级功能深度解析超越基础翻译当你掌握了基础三步后XUnity.AutoTranslator的强大之处才刚刚开始。它不仅仅是一个翻译器更是一个强大的游戏文本修改和资源替换框架。3.1 纹理翻译替换游戏内的图片资源这是插件一个非常强大的功能允许你替换游戏内的UI图标、背景图甚至立绘。想象一下把日文的菜单按钮图片直接替换成中文版图片。原理与配置插件通过XUnity.ResourceRedirector库在游戏加载图片资源时进行拦截和重定向。你需要开启相关配置并准备替换用的图片。启用纹理翻译在配置文件的[Texture]部分进行设置。[Texture] EnableTextureTranslationTrue EnableTextureDumpingTrue ;首次使用时开启用于导出游戏内所有纹理 TextureDirectoryTranslation\Texture TextureHashGenerationStrategyFromImageNameEnableTextureTranslationTrue核心开关。EnableTextureDumpingTrue仅在初次配置时开启。运行游戏后插件会将游戏加载的纹理图片导出到TextureDirectory指定的目录。导出完成后务必将其改回False否则每次运行都会重新导出严重影响性能。TextureHashGenerationStrategy推荐使用FromImageName。插件通过哈希值来匹配游戏内的纹理和你要替换的图片。这个策略根据纹理的内部资源名生成哈希性能最好。制作与替换纹理 运行游戏并浏览各个场景让插件导出纹理。导出的图片文件名会包含哈希值例如menu_button [0223B639A2-6E698E9272].png。 用图像处理软件如Photoshop、GIMP打开对应的图片将其中的日文/英文修改为中文保持图片尺寸、格式和文件名中的哈希值完全不变。 将修改后的图片放回Translation\Texture目录或子目录。下次运行游戏对应的纹理就会被自动替换。重要警告分发整合包时绝对不要开启EnableTextureDumping、EnableTextureToggling、LoadUnmodifiedTextures或DetectDuplicateTextureNames。这些选项仅供调试使用会严重影响最终用户的游戏性能。3.2 正则表达式与文本预处理处理复杂文本格式游戏文本并非总是规整的句子。可能是带有变量、编号或特殊格式的字符串例如“获得了 {itemName} x {count}”。直接翻译会导致变量部分也被送翻结果惨不忍睹。1. 使用替换文件Substitutions在Translation\{Lang}\Text\_Substitutions.txt文件中可以定义简单的文本替换规则在翻译前执行。プレイヤー玩家 メニュー菜单这会在翻译前将“プレイヤー”替换为“玩家”这样翻译API接收到的是“玩家”避免了错误的翻译。2. 使用标准正则表达式Regex对于更复杂的模式匹配可以使用正则表达式。在任意翻译文件除了以_开头的自动生成文件中以r:开头定义。r:^アイテム([0-9])$物品$1这个正则表达式会匹配像“アイテム123”这样的文本并将其翻译为“物品123”。$1代表正则中第一个捕获组的内容即数字部分。3. 使用分割器正则表达式Splitter Regex这是处理组合文本的终极武器。有时游戏会将多个文本拼接后再显示例如“01 ポーション”。使用分割器正则以sr:开头可以将其拆开分别翻译后再组合。sr:^([0-9]{2}) ([\S\s])$$1 $2这个表达式将“01 ポーション”拆分为“01”和“ポーション”。插件会先查找“ポーション”的翻译假设你手动翻译了“ポーション药水”然后将结果组合为“01 药水”。实操心得正则表达式功能强大但复杂使用需谨慎。错误的表达式可能导致性能下降或翻译失效。始终先在_AutoGeneratedTranslations.txt中观察游戏实际输出的原始文本格式再设计对应的正则规则。分割器正则支持命名捕获组和递归可以处理极其复杂的嵌套结构但这属于高阶用法需要扎实的正则表达式功底。3.3 翻译作用域与插件特定翻译当你为多个游戏使用同一个翻译插件或者一个游戏有多个可执行文件如本体和DLC时翻译作用域就非常有用。1. 基于场景Level的作用域在翻译文件中可以使用指令来限定翻译只在特定场景生效。#set level 5 商店Shop #unset level这行“商店Shop”的翻译只会在场景ID为5时生效。你可以按CTRLALTNP7在游戏中查看当前加载的场景ID。2. 基于可执行文件的作用域更常见的是为不同的游戏配置不同的翻译目录。在[Files]部分可以使用{GameExeName}变量。[Files] DirectoryTranslation\{GameExeName}\{Lang}\Text OutputFileTranslation\{GameExeName}\{Lang}\Text\_AutoGeneratedTranslations.txt这样游戏GameA.exe的翻译文件会放在Translation\GameA\zh-CN\Text\下与GameB.exe的完全隔离互不干扰。3. 为其他Mod提供翻译如果你安装的某个Mod界面是英文的你也可以为它单独提供翻译。在Translation\{Lang}\Text\目录下创建Plugins文件夹再在里面为每个Mod的DLL文件去掉.dll后缀创建一个同名文件夹将翻译文件放入即可。你甚至可以在翻译文件中添加#enable fallback指令让Mod的翻译在找不到时回退到全局自动翻译。4. 开发者视角自定义翻译端点与资源重定向对于有一定编程基础的玩家或Mod开发者XUnity.AutoTranslator提供了强大的扩展能力。4.1 实现自定义翻译端点如果你不想依赖公共的谷歌/百度翻译或者有私有的翻译API可以实现自己的ITranslateEndpoint接口。核心步骤创建类库项目使用Visual Studio等工具创建一个面向 .NET Framework 3.5 的类库项目因为大多数Unity游戏使用此版本。引用插件核心库添加对XUnity.AutoTranslator.Plugin.Core.dll的引用可从开发者包中获得。实现接口创建一个类实现ITranslateEndpoint接口或继承自HttpEndpoint等辅助类。你需要提供Id配置中使用的标识符、FriendlyName显示名称并在Initialize方法中读取配置、验证API密钥在Translate或OnCreateRequest/OnExtractTranslation方法中实现网络请求和结果解析。处理网络请求强烈建议使用插件内置的XUnityWebClient类它解决了Unity旧版本Mono中HTTP请求的许多坑如SSL证书验证、连接池管理。编译与部署将编译好的DLL文件放入游戏的BepInEx\plugins\XUnity.AutoTranslator\Translators\目录。然后在配置文件中将Endpoint设置为你实现的端点ID即可。一个简单的反向翻译器示例public class ReverseTranslatorEndpoint : ITranslateEndpoint { public string Id ReverseTranslator; public string FriendlyName 文本反转器; public int MaxConcurrency 10; public int MaxTranslationsPerRequest 1; public void Initialize(IInitializationContext context) { // 可以在这里读取自定义配置 // bool mySetting context.GetOrCreateSetting(MyTranslator, MyConfig, true); } public IEnumerator Translate(ITranslationContext context) { // 这是一个玩笑式的“翻译”仅仅把文本反转 char[] charArray context.UntranslatedText.ToCharArray(); Array.Reverse(charArray); string reversedText new string(charArray); // 完成翻译 context.Complete(reversedText); yield break; // 对于同步操作直接返回null或break } }4.2 利用资源重定向API进行深度修改XUnity.ResourceRedirector是一个独立的、强大的库允许你在游戏加载任何资源纹理、音频、文本资产、预制体等时进行拦截和修改。AutoTranslator的纹理翻译功能就是基于它实现的。常见用途替换游戏音频将语音或背景音乐替换为其他版本。修改游戏字体直接替换游戏使用的字体资产文件。汉化非文本资源替换包含文字的图片资源如技能图标上的文字。修改游戏数据替换TextAsset如JSON、XML配置文件来调整游戏平衡性或内容。基本使用模式你需要创建一个BepInEx插件在Start方法中注册钩子。public class MyResourceModPlugin : BaseUnityPlugin { void Start() { ResourceRedirection.RegisterAssetLoadedHook(HookBehaviour.OneCallbackPerResourceLoaded, 0, OnAssetLoaded); } private void OnAssetLoaded(AssetLoadedContext context) { // 检查加载的资源类型和路径 if (context.Parameters.LoadType AssetLoadType.LoadNamed context.Parameters.Name.Contains(MyTargetTexture)) { // 例如加载我们自己的纹理来替换 Texture2D myTexture LoadMyCustomTexture(); if (myTexture ! null) { context.Asset myTexture; // 替换资源 context.Complete(); // 告知重定向器处理完成 } } } }注意事项资源重定向是底层操作不当使用极易导致游戏崩溃。需要精确知道你要修改的资源的内部路径和名称这通常需要通过逆向工程或使用LogAllLoadedResourcesTrue配置来探查。替换资源时必须确保新资源与旧资源的类型、尺寸等属性兼容。5. 实战排坑与性能优化指南即使按照步骤操作在实际使用中仍会遇到各种问题。这里汇总了我多年来遇到的高频问题及其解决方案。5.1 常见问题速查表问题现象可能原因解决方案游戏启动崩溃BepInEx日志报错BepInEx版本与游戏不兼容插件依赖缺失游戏为IL2CPP但未使用专用版本。1. 尝试更新或降级BepInEx版本。2. 确保XUnity.Common.dll和XUnity.ResourceRedirector.dll存在。3. IL2CPP游戏使用BepInEx-Unity.IL2CPP版本。游戏运行正常但无任何翻译翻译端点配置错误网络问题文本未被正确钩住。1. 按ALT0检查端点是否已选择并启用。2. 开启控制台 (EnableConsoleTrue) 查看翻译请求日志。3. 尝试切换翻译端点如从GoogleTranslate换到BaiduTranslate。4. 对于IL2CPP游戏尝试安装AutoTranslator.IL2CPP.BruteForceFix插件。翻译后出现“□□□”豆腐块游戏字体不支持目标语言字符。1. 配置OverrideFontTextMeshPro指向一个支持中文的TMP字体资产。2. 寻找或制作包含目标语言字形的.assetbundle字体文件。翻译后UI布局错乱、文字溢出翻译文本长度远超原文UI组件尺寸不足。1. 确保[Behaviour] EnableUIResizingTrue。2. 使用resizer.txt文件手动调整特定UI路径的字体大小或溢出模式。3. 尝试修改[Behaviour] ForceSplitTextAfterCharacters值让长文本自动换行。翻译导致游戏逻辑错误如选项无法点击游戏通过检查显示文本来执行逻辑。设置[Behaviour] TextGetterCompatibilityModeTrue。此模式会欺骗游戏使其“看到”的仍是原始文本。翻译请求缓慢游戏卡顿网络延迟翻译端点限流MaxCharactersPerTranslation值过大。1. 更换更稳定的翻译端点如使用API密钥的百度/DeepL。2.将MaxCharactersPerTranslation降至150-200。3. 开启[Behaviour] EnableBatchingTrue以批量发送翻译请求。特定插件/Mod的界面未被翻译IMGUI翻译默认关闭插件UI被故意忽略。1. 设置[Behaviour] EnableIMGUITrue以启用IMGUI翻译。2. 某些Mod可能使用了XUAIGNORE标记需要联系Mod作者调整。纹理替换功能不工作纹理翻译未启用哈希生成策略不匹配图片未正确放置。1. 确认[Texture] EnableTextureTranslationTrue。2. 确认TextureHashGenerationStrategy与图片文件名中的哈希生成方式一致首次导出时决定。3. 替换的图片必须放在TextureDirectory目录或其子目录下且哈希值文件名部分必须保留。5.2 性能优化与最佳实践为了让翻译体验更流畅减少对游戏性能的影响请遵循以下准则精简自动翻译文件定期清理_AutoGeneratedTranslations.txt。将翻译满意、无需改动的条目剪切到新的手动翻译文件中如ManualTrans.txt。自动翻译文件越大插件启动时加载和索引的耗时就越长。善用翻译缓存插件会将所有翻译包括自动和手动缓存在内存中。确保你的手动翻译文件准确覆盖了高频词汇这样可以最大限度减少对在线翻译API的请求。禁用不必要的日志在稳定使用后将[Debug]下的EnableLog设为False可以减少日志输出对磁盘I/O和性能的轻微影响。谨慎使用正则和纹理替换正则表达式匹配和纹理加载/替换都是相对耗时的操作。确保你的正则表达式是高效且必要的对于纹理替换只替换真正需要翻译的UI元素并确保CacheTexturesInMemoryTrue默认以用内存换取加载速度。分发配置的注意事项如果你制作了游戏的汉化整合包并分享给他人务必禁用所有调试选项EnableTextureDumping,EnableLog,OutputUntranslatableText等。将MaxCharactersPerTranslation设置为400或更低。提供尽可能完整的手动翻译文件减少用户对在线API的依赖。如果包含替换纹理使用TextureHashGenerationStrategyFromImageName并清理未翻译的图片。5.3 手动翻译的艺术依赖机器翻译始终有局限。对于重要的剧情对话、物品描述、技能说明手动润色能极大提升体验。编辑翻译文件所有放在Translation\{Lang}\Text\目录下的.txt文件都会被加载。你可以直接编辑_AutoGeneratedTranslations.txt但更推荐将修改后的条目移动到新建的文件中如Dialogue.txt,Items.txt。因为自动生成文件优先级最低且可能被插件重写。理解文件格式每行一个翻译对格式为原文译文。等号两边不要有多余空格除非原文就有。支持使用\n表示换行。处理变量文本对于包含动态变量的文本如“你击败了 {monster}”在手动翻译中保留变量占位符你击败了 {monster}You defeated {monster}。插件会智能地处理参数化。利用上下文注释虽然插件不支持注释但你可以在翻译条目附近添加以#开头的行作为给自己看的备注插件会忽略它。例如# 这里是商店老板的问候语 いらっしゃいませ欢迎光临经过这三步的深入实践你不仅能解决“玩不了”的问题更能进阶到“玩得好”的层次。XUnity.AutoTranslator就像一把打开语言壁垒的万能钥匙但其真正的力量在于它提供的深度定制能力。从简单的文本替换到复杂的资源重定向它让玩家社区能够对游戏进行深度的本地化改造。记住核心永远是三步搭好环境BepInEx插件、配好引擎Endpoint、游戏中调试热键日志。剩下的高级功能都是在解决特定痛点时逐步探索的利器。