proxy不能用于unity游戏翻译,因其仅适用于javascript环境,而unity文本渲染在c#层(如text.text、tmp_text.text),且xunity.autotranslator采用il指令重写或函数注入实现钩子,与js proxy技术栈完全不同。

为什么 Proxy 不能直接用于 Unity 或游戏运行时的翻译劫持
Proxy 对象只能拦截 JavaScript 环境中对普通对象属性的读写,而 Unity 游戏的文本渲染发生在 C# 层(如 Text.text、TMP_Text.text),JS 无法触及。XUnity.AutoTranslator 的“钩子”本质是 IL 指令重写或函数地址注入,和 JS Proxy 完全不在同一技术栈。强行在浏览器里用 Proxy 模拟游戏内翻译,会漏掉所有非 DOM 文本(比如 Canvas 渲染文字、Shader UI、动态生成的 SpriteFont 文字),也绕不开 Unity 的资源加载生命周期。
Proxy 在网页环境里做全路径翻译的实际限制
即使只考虑网页场景,Proxy 劫持也仅适用于明确赋值的 JS 对象,比如 i18n.messages.home.title。它无法自动捕获以下情况:
- DOM 中直接写死的文本:
<h1>Welcome</h1>不经过任何 JS 对象 - Vue/React 组件中未绑定到响应式数据的字符串字面量
- 通过
innerHTML、textContent批量写入的文本(Proxy 不监听 DOM 变更) - 第三方库内部构造的字符串(如 ECharts 图表标题、Monaco 编辑器提示)
真正能覆盖“全路径”的不是 Proxy,而是基于 MutationObserver + document.querySelectorAll 遍历 + 白名单过滤的实时 DOM 扫描策略——这也是 translate.js 实际采用的方式。
如果坚持用 Proxy,必须配合哪些补救措施
仅靠 new Proxy({}) 做翻译映射,连基础功能都不可靠。要让它勉强可用,得叠加三层机制:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
- 用
Reflect.get拦截嵌套路径访问,并支持通配符 fallback(如i18n['zh-CN'].menu?.settings || i18n.fallback.menu.settings) - 手动 patch 所有已知的文本输出点:重写
console.log、拦截Element.prototype.textContentsetter、包装Intl.NumberFormat等原生 API - 主动扫描并替换现有 DOM 文本节点,且需排除
code、pre、textarea等禁止翻译区域
这些操作本身就会破坏原有代码行为,比如重写 textContent setter 可能导致 Vue 的响应式更新失效,或让某些依赖原生 setter 的 UI 库崩溃。
真正的无侵入式翻译,核心不在“劫持”,而在“时机”
无论是 translate.js 还是 XUnity.AutoTranslator,它们的“无侵入”本质是:不修改原始业务代码结构,但必须在关键执行点插入控制权。区别在于:
- 网页侧靠
MutationObserver+requestIdleCallback监听 DOM 变化,在渲染后、用户可见前完成翻译 - Unity 侧靠
Harmony或ILHook注入到Text.SetPropertyBlock、TMP_Text.set_text等真实渲染入口
想用 Proxy 实现“全路径”翻译,等于试图用锁眼去撬保险柜——方向错了。该关注的是文本何时被真正提交给渲染管线,而不是它在 JS 对象树里叫什么名字。










