尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Unity游戏汉化新思路:XUnity.AutoTranslator注入式翻译完全指南

Unity游戏汉化新思路:XUnity.AutoTranslator注入式翻译完全指南 常玩Unity引擎游戏的人应该都经历过这种尴尬游戏库里的冷门独立佳作画面、玩法都戳中你但界面和对话全是英文、日文或者韩文啃起来实在费劲。等汉化组的大佬出手又不现实小众游戏很可能根本没有汉化计划。XUnity.AutoTranslator就是用来解决这个问题的它是一个运行在游戏进程内部的翻译插件不需要改动游戏原文件也不依赖官方支持启动游戏后自动拦截并翻译屏幕上的文本。用它汉化一个Unity小游戏从下载工具到真正看到中文界面熟练的话确实能在五分钟左右跑通。这篇文章我会从方案选择、安装配置一直写到离线词典和问题排查把我实际用下来的经验、踩过的坑一并放进去。不管是刚接触游戏汉化的新玩家还是想研究翻译管线原理的爱好者照着这套流程走大部分Unity引擎的游戏都能顺利啃下来。文章涉及的内容全部基于公开的通用技术只讲技术实现思路你可以放心跟着操作。1. 为什么选XUnity.AutoTranslator方案对比与底层原理1.1 三种主流汉化方案为什么我选注入式说到汉化大家最先想到的可能是汉化组发布的汉化补丁。这类补丁通常分两种思路一种是直接修改游戏资源包把文本文件解包、翻译、再封回去另一种是外挂字幕式的翻译用额外程序识别画面并覆盖显示。这两种方式在传统PC游戏里很成熟但放到Unity游戏上有个尴尬Unity的资源打包方式和传统游戏差异很大不同项目的资源结构几乎没有统一标准。今天汉化A游戏需要拆AssetBundle明天汉化B游戏又要解包Addressables每个游戏都要定制一套解包封包流程个人玩家折腾成本太高。XUnity.AutoTranslator走的是第三条路运行时注入翻译。它不碰游戏文件而是在游戏启动后从内存层面对文本进行拦截和替换。游戏本身该按什么逻辑运行还是按什么逻辑运行翻译插件只是夹在“游戏要显示文字”和“文字被画到屏幕上”之间做一个中转。三种方案的区别我整理了一张表方案类型是否修改游戏文件对新手友好度版本更新兼容性文本可控性资源包解包汉化是低需要熟悉Unity资源格式较差游戏更新后补丁基本要重做高可以精修每一条文本外挂字幕式翻译否中需要额外抓屏识别较好一般容易和界面位置对不齐运行时注入翻译否高安装配置一次搞定较好插件独立于游戏资源较高配合离线词典可以精确控制我在试过前两种之后基本是稳定选第三种了。原因很现实大部分个人汉化场景并不追求“发布一个完美汉化包”只是想让游戏能舒服地玩下去。注入式方案把安装成本降到了最低而且游戏本体文件没动过Steam检查完整性也不会报错退出插件就是原版风险小很多。1.2 XUnity.AutoTranslator的工作原理要理解这个插件得先简单说下Unity引擎的文本显示机制。Unity早期的主流脚本后端叫Mono游戏里的UI文本、对话内容最终都会从脚本层传到引擎层再由底层绘图函数把字形画到屏幕上。XUnity.AutoTranslator做的事情就是把那些负责“画文字”的函数入口拦下来读取它要绘制的字符串提交给翻译引擎翻译再把译文交给原来的函数继续绘制。整个替换过程发生在内存里游戏文件没有被修改所以它被称为“注入式”工具。插件内部有几个核心组件。首先是加载器它负责把插件注入到游戏进程中BepInEx就是其中最常用的加载器之一其次是Hook层负责拦截文本绘制相关的函数调用然后是翻译引擎负责把原文发送到翻译服务并取回译文最后还有缓存机制负责把翻译过的句子存到本地避免下次遇到相同的文本再次请求翻译。把原理弄明白之后很多使用上的问题就能解释通了。比如为什么同一句话第二次出现时翻译很快因为缓存命中了为什么某些游戏里翻译生效但UI布局有点怪因为译文长度和原文不同而UI的排版是根据原文宽度计算的为什么有的文本没被翻译因为游戏可能用了特殊的文本渲染路径插件默认的Hook没有覆盖到。这些细节在后面章节会逐一展开。2. 环境准备与安装拿到文件就能跑2.1 下载前先确认你的游戏能不能用XUnity.AutoTranslator对目标游戏是有适配范围的不是所有Unity游戏都能直接生效。动手之前先花两分钟确认游戏类型能避免后面白折腾。第一看游戏是不是Unity引擎做的。Steam商店页、游戏启动画面、目录结构都能作为判断依据。Unity游戏的根目录下通常会有一个以“游戏名_Data”命名的文件夹里面放着globalgamemanagers、resources.assets等资源文件有些游戏根目录还会有UnityCrashHandler64.exe这样的辅助程序。第二看游戏的脚本后端。老一些的Unity游戏默认使用Mono后端这类游戏对XUnity.AutoTranslator支持最好。新一些的项目可能改用IL2CPP把C#编译成C再打包文本渲染路径变了一截插件的支持就会弱一些。简单判断方法是看游戏目录里有没有GameAssembly.dll一般有这个文件就可能是IL2CPP如果看到Mono目录或者MonoBleedingEdge这样的文件夹基本就是Mono后端。IL2CPP游戏有一部分也能用但功能会受限比如对部分文本渲染方式的拦截可能不到位。第三确认游戏没有强反作弊系统。像一些竞技类游戏、带内核级反作弊的游戏注入任何外部模块都可能触发风控。我的建议是XUnity.AutoTranslator只用在单机游戏上联机游戏尤其是有反作弊的联机游戏不要折腾这个既容易出问题也不符合游戏规则。2.2 两步安装BepInEx与插件目录确认游戏适用后安装其实就两步。第一步下载BepInEx加载器第二步把XUnity.AutoTranslator的插件文件放进加载器目录。BepInEx是一个开源的游戏插件加载框架名字拆开是“Beppy Unity Injector”它在Unity游戏社区里使用非常广泛音频替换、图形增强、玩法修改等各种插件都依赖它。XUnity.AutoTranslator也提供了基于BepInEx的分发包所以我个人最推荐用这种方式安装。具体的目录结构应该是这样游戏根目录/ ├─ 游戏可执行文件.exe ├─ 游戏名_Data/ ├─ BepInEx/ │ ├─ core/ │ ├─ plugins/ │ │ └─ XUnity.AutoTranslator/ │ │ ├─ AutoTranslatorConfig.ini │ │ ├─ Translation/ │ │ └─ ... │ ├─ config/ │ └─ LogOutput.log ├─ doorstop_config.ini └─ winhttp.dll实际操作时先把BepInEx压缩包解压到游戏根目录再把XUnity.AutoTranslator的压缩包解压后放到BepInEx/plugins文件夹下。这里有个关键点网上很多教程让人直接双击游戏主程序其实第一次最好先从命令行或文件管理器直接启动不要通过Steam启动器避免启动器做文件校验时把新加的文件干掉。首次启动游戏后插件会创建两样东西一个是AutoTranslatorConfig.ini配置文件另一个是Translation文件夹。看到这两个东西生成说明插件已经成功注入了。如果没生成优先去BepInEx/LogOutput.log里看加载日志后面问题排查章节会细说。3. 核心配置看懂配置文件汉化就成功了一半3.1 AutoTranslatorConfig.ini关键参数插件的所有核心行为都被集中到AutoTranslatorConfig.ini这个文件里。第一次打开它你会看到很多配置项英文又长容易让人头疼。但其实真正要动的就那么几个我把我常用的配置贴出来并逐一说明。[General] Languagezh-CN FallbackLanguagezh-CN [Service] EndpointBingTranslate FallbackEndpointGoogleTranslateV2 MaxConcurrentTranslations8 MaxCharactersPerTranslation150 DelayBetweenTranslations100 [Cache] UseCachetrue [Behaviour] OverwriteTranslationsfalse DumpTranslationfalse先看[General]里的Language这个决定目标语言写zh-CN就是简体中文。有的版本也接受zhs或者SimplifiedChinese这种写法认不准就看插件文档里的语言代码表统一用小写短横线格式基本不会错。[Service]这一组是重中之重。Endpoint是翻译引擎插件的设计思路是通过统一的接口对接各种翻译服务你可以在这里切换不同的端点。我实测下来BingTranslate对中文的支持比较稳定响应速度也理想适合作为默认选择。FallbackEndpoint是备用引擎当第一个引擎请求失败时插件会自动切换过去。同时还可以调整MaxConcurrentTranslations最大并发翻译数和DelayBetweenTranslations每次请求之间的间隔毫秒数。这两个参数要配合着调并发数调太高容易被翻译服务限流间隔调太短同样可能被限流。我在个人使用中一般并发8、间隔100毫秒稳定性和速度比较均衡。如果你网络环境对某些公共接口响应慢可以试着把并发降下来再把间隔稍微调大优先保证不超时。[Cache]里的UseCache建议永远保持true。这是个本地缓存开关开启后每条译文都会存到本地同一句话第二次遇到时直接读缓存不用再请求翻译服务对速度和成本都是巨大优化。[Behaviour]里有两个容易混淆的开关。OverwriteTranslations控制是否允许覆盖已有翻译默认false表示“如果离线词典里已经有译文就不再用在线翻译”。DumpTranslation是文本转储开关后面进阶章节会单独讲平时保持false就好。3.2 字体替换解决汉字变成“口口口”第一次跑通翻译的人十有八九会碰到一个经典问题游戏里文字确实变成了中文但所有字符都显示成方框或者“口口口”。这不是翻译失败翻译其实成功了只是游戏默认字体里根本没有中文字形。Unity游戏的字体会被打包进资源文件里不同游戏自带字体的字符集差异很大。英文游戏的自带字体往往只包含拉丁字母、数字和符号你把中文塞进去引擎找不到对应的字形就只能画一个方块占位。解决办法是让插件强制替换游戏使用的字体文件。具体步骤下载一个包含简体中文的字体文件比如思源黑体、NotoSansCJK等开源字体把字体文件命名为Font.ttf放到游戏根目录然后在配置文件里把[Behaviour]区域的OverrideFont设置成Font.ttf。重启游戏后插件就会在绘制文本前把默认字体换成这个字体文件。字体替换这块有几个坑需要提一下。第一字体文件体积别太大中文字体本身动辄十几兆如果游戏里要频繁切换字体样式可能造成加载卡顿。第二思源黑体这类字体有多种字重如果只提供常规字重游戏里加粗文字可能会渲染异常你可以把加粗变体也一并放进目录并用OverrideFontBold指定。第三替换字体后原来英文UI的排版宽度会发生变化中文单字本身占宽更多有些按钮或对话框可能出现文字顶到边缘的情况这个属于Unity版面适配问题通常不影响使用介意的话只能靠离线词典把长文本改短一些。4. 5分钟实操流程从解压到跑通4.1 完整操作步骤与验证方法理论知识过了一遍现在走一遍完整实操。我以我最近处理的一款Unity单机游戏为例把每一步拆开来说。第一步备份。把游戏根目录下的存档文件夹整体复制一份同时如果游戏在Steam上有云存档先确认云存档同步完成。备份存档是为了防止插件在极少数情况下导致崩溃存档面前无小事。第二步下载并解压BepInEx。从BepInEx的GitHub Release页面找到对应游戏架构的发行版Windows平台一般下载x64版本即可。把压缩包解压到游戏根目录解压后应出现BepInEx文件夹、winhttp.dll、doorstop_config.ini等文件。这一步做完先别急着装翻译插件直接启动一次游戏再退出让BepInEx把它的基础目录结构生成完整。第三步解压XUnity.AutoTranslator。从插件的GitHub Release页面下载与BepInEx对应的版本解压后把内含的XUnity.AutoTranslator文件夹整个放到BepInEx/plugins目录下。第四步配置。启动游戏插件会生成默认配置文件。退出游戏打开AutoTranslatorConfig.ini把Language改成zh-CNEndpoint改成BingTranslate缓存保持开启先把字体替换关掉其他保持默认。这一步的核心理念是“先跑通再优化”不要一上来就改一堆参数否则出了问题很难判断是哪一处配置引起的。第五步重新启动游戏进入任意有文本的场景。正常情况下几秒钟后英文/日文原文会陆续变成中文。如果你玩的是日文游戏还会发现文本出现顺序是先原文后译文这是因为翻译请求需要一点网络往返时间。此时打开BepInEx/LogOutput.log能看到插件输出的翻译日志包括正在翻译的文本、请求的端点、耗时等信息这些日志后面排查问题特别有用。第六步验证缓存。玩一小段后退出游戏打开插件的Translation目录应该能看到按语言划分的缓存文件夹里面已经有刚才翻译过的文本记录。能走到这一步说明整个管线已经通了。4.2 为什么有时要等好几秒才出中文很多人在第五步会被“等待时间”吓住怀疑插件是不是卡死了。其实首次运行的前几秒插件做的事比看起来多得多。它要向翻译服务发送一段段文本等待响应再把译文回填到游戏界面。如果游戏同一个画面里塞了几十段文本而配置里的并发数又比较保守队列消化需要时间体感就是“翻得慢”。我自己有一个经验参数组合玩剧情密集的游戏内容量大、句子短、重复多我会把并发调到10到12间隔调到100毫秒这样一屏多文本也能快速消化玩文本量小的游戏比如操作菜单为主的并发保持默认就足够了。但要注意并发不是越高越好我试过把它调到30结果某个翻译端点直接开始返回限流错误翻译质量没变差但日志里全是一串一串的错误反而不如之前稳定。缓存是另一个被低估的加速器。第一次进游戏时翻译慢第二次进同一个场景几乎瞬间就出中文这就是缓存命中的效果。经验是别频繁清理缓存目录缓存文件夹哪怕积累到几万条记录也不用太担心文本文件本身占不了太多空间。但反过来如果你怀疑某些翻译内容已经在缓存里变成“错误翻译”了那就要找到对应词条手动修改或者删除而不是清空整个缓存。5. 进阶玩法离线词典、文本转储与Mod翻译5.1 离线词典与自定义词条让专有名词不再“乱翻”在线翻译能解决大部分通用句子的翻译但游戏里的人名、地名、专属术语在线翻译往往翻得莫名其妙。比如奇幻游戏里的城市名很可能被直译成一句没有意义的词组。这时候离线词典就是你的控制开关。插件的Translation文件夹下会有一个与目标语言对应的子文件夹把自定义词条放进里面就可以。支持的格式很直观每行一条等号左边是原文右边是译文Alduin奥杜因 Whiterun白漫城 The Elder Scrolls V: Skyrim上古卷轴5天际这个机制的优先级很有意思离线词典里已有的词条会直接覆盖在线翻译的结果。利用这一点我可以先把高频的人名、地名、道具名全部写进词典保证游戏里这些专有名词从头到尾保持统一。游戏更新后文本变了离线词典文件还在只需要补充新出现的词条即可。更进阶的用法是配合正则表达式。词典文件支持按正则规则匹配批量替换比如把所有的“HP Potion”批量映射成“生命药水”甚至可以根据上下文做条件替换。这个功能对文本量很大的RPG特别有用但正则规则复杂新手建议先从精确匹配的“原文译文”开始用跑稳了再学批量规则。5.2 文本转储把游戏文本抽出来整理如果你想追求比机器翻译更好的阅读体验文本转储功能值得研究。把配置文件里的DumpTranslation临时改成true插件在翻译的同时会不断把游戏中实际出现的原文追加记录到一个文本文件里。这个功能的价值在于你可以得到一个带上下文的完整文本清单。收集到一定量后把文本导出用表格软件打开手动修改不清楚的翻译改完再以离线词典的形式放回插件。这样操作下来同一个游戏内部出现的专有名词、语气词、习惯用语都能做到全局统一而不是掉进在线翻译“上一句和下一句翻法都对不上”的坑里。整套流程其实就是个人汉化的精简版机器初翻、人工精修、词典回填。规模肯定比不上汉化组几千条文本的工程但对一个体量中等的单机游戏来说这个工作流完全可行。我经常在周末挑一个文本量不大的短篇游戏花半天时间挑重点对话润色一遍玩起来的感觉完全不同。5.3 Mod文本与游戏外的扩展场景XUnity.AutoTranslator还有一个常被忽视的能力支持翻译Mod新增的文本。很多Unity游戏以Modding著称Mod会往游戏里添加新的物品、任务、对话。这些Mod文本同样走Unity引擎的文本管线只要Mod作者没有用特殊的不受拦截的方式绘制文字插件都能一并翻出来。配置里面跟Mod相关的开关建议保持默认开启对原版文本不会有影响但能覆盖到Mod场景。说到游戏外我也用这套工具做过几次Unity原型开发时的调试。当时项目的界面文案只有英文给客户演示时想临时改成中文重新打包成本高直接用XUnity.AutoTranslator注入一次十分钟就把演示版本的中文界面跑通了。这类用法在个人开发、测试、演示场景里非常实用相当于把翻译插件用成了“运行期资源替换工具”。6. 常见问题与排查技巧实录6.1 高频问题速查表这几年用下来XUnity.AutoTranslator相关的问题基本集中在下面几个方向。我整理成一张速查表遇到问题先对号入座。现象常见原因解决思路装上后游戏里没有翻译插件没有被正确加载看BepInEx/LogOutput.log里有没有插件加载记录文字变成“口口口”游戏字体不含中文字形配置字体替换指定一个中文字体文件部分文本被翻译部分没有游戏用了不支持的文本渲染路径更新插件版本或确认是否属于已知兼容性问题翻译请求一直超时当前Endpoint响应慢或被限流切换备用Endpoint调低并发数调大间隔游戏启动崩溃插件与游戏/其他加载冲突临时移走plugins下其他插件逐个排除同一句话每次翻译结果不一样在线翻译结果不稳定用离线词典固定词条杀毒软件提示有风险文件注入式工具被误报加入信任区确认安装包来源可靠后使用游戏更新后恢复原版启动器清理了额外文件重新解压安装保留Translation缓存目录这个表解决八成问题没问题。那剩下两成基本要靠日志定位了。6.2 排查思路与独家技巧排查XUnity.AutoTranslator问题的第一步永远是看日志。BepInEx/LogOutput.log记录了插件的加载过程、配置解析结果、每条文本的翻译请求和错误原因。有一次我自己折腾一个老游戏装完插件完全没反应第一反应就去翻日志结果发现插件根本没有被加载原因是BepInEx版本太老插件要求的加载接口不存在。换新版本BepInEx后一次通过。这个案例说明日志永远是最可靠的突破口。排查的第二个建议是“做减法”。配置项先全部还原成默认插件也只保留XUnity.AutoTranslator这一个其他功能插件全部移出plugins文件夹然后在默认配置下测试。如果默认配置能翻再一项一项把自定义配置加回去哪一步出问题就是哪一项的锅。我见过有人一上来就开十几个插件结果翻译不生效最后发现是内存修改类插件和翻译插件的Hook函数互相覆盖了。这个问题不用“减法”翻一天日志都不一定能找到。第三个技巧是关于请求参数的。很多人为了让句子翻译完整把MaxCharactersPerTranslation调得很大其实没必要。翻译服务对单条文本长度通常有上限而且长文本翻译耗时长、失败率高。游戏里那些长句插件会智能分段处理你只要保持参数在合理范围就行。我记得有一次想翻一个特别长的剧情文本反而让翻译卡住后来把单条长度上限调小句子被拆成多段反而顺利出译文了。还有一点容易被忽视插件不会主动重翻已经缓存的句子。如果你更新了词典但游戏里那句话还是显示旧的翻译多半是旧译文还在缓存里。解决办法有两个要么在词典更新后手动删除对应缓存文件要么在配置文件里打开OverwriteTranslations开关让词典覆盖缓存。这里我推荐用前者因为OverwriteTranslations打开会让所有在线翻译结果也覆盖词典词条反而可能把精心修改的词条冲掉。最后分享两个实用经验第一一开始装的时候尽量把“先跑通核心流程”当目标。先别管字体、别管词典、别管Mod先把翻译验证出来再逐步叠加工序。很多人第一步就栽在“字体替换词典翻译Mod”同时上出了问题根本不知道从哪儿排查。我的习惯是先默认配置跑通成功后再加字体能正常显示中文了再加词典每一步都有明确验证点整个流程会顺很多。第二用好缓存目录这个“金矿”。有些游戏你玩到后期缓存里已经积累了几千条词条这其实是自己用脚投票生成的一部“游戏术语词典”。我把每个游戏的Translation缓存目录单独备份同一个系列的游戏之间可以互相复用。比如玩过一代再玩二代一代缓存里的那些人名、地名把文件挪过去直接就能命中二代需要重新翻译的新词条少了一大截整个汉化过程快到飞起。这个用法不需要什么高深技术但绝对能让你在朋友面前显得很专业。
返回列表