XUnity.AutoTranslator não está traduzindo
O XUnity.AutoTranslator é o melhor tradutor em tempo de execução que o Unity tem e, quando ele fica em silêncio, o motivo é quase sempre uma de cinco coisas específicas: o jogo é uma build IL2CPP, o texto é definido por um caminho que o hook não intercepta, o framework de UI que o desenha não está habilitado, a linha passa do limite de caracteres, ou o endpoint se desligou sozinho. Veja como descobrir qual é o seu caso.
O XUnity.AutoTranslator é gratuito, licenciado sob MIT, mantido ativamente e a melhor ferramenta de tradução em tempo de execução que o Unity tem. Ele funciona interceptando o momento em que o jogo entrega uma string a um componente de texto e trocando por uma tradução antes de ela ser desenhada. É por isso que ele não precisa saber nada sobre os formatos de arquivo do jogo — e é também por isso que, quando falha, ele falha em silêncio. Nada trava. O jogo simplesmente continua em japonês.
As cinco causas abaixo respondem por quase todo relato de "não está traduzindo". Trabalhe nelas em ordem; cada uma tem uma correção diferente, e ficar chutando entre elas custa muitas noites.
Primeiro: leia o log, não a tela
O plugin é falante sobre o que está fazendo, e o log é o único lugar onde ele diz isso. Com uma instalação do BepInEx, olhe BepInEx/LogOutput.log. O log do próprio Unity fica ao lado, em <Game>_Data/output_log.txt nas builds mais antigas, ou em %APPDATA%/../LocalLow/<Company>/<Game>/Player.log nas mais novas.
- O log menciona o XUnity.AutoTranslator carregando? Se não, o problema é o loader, não o tradutor — você está na causa número um.
- Ele lista um endpoint sendo inicializado e, mais adiante, cita um sendo desligado depois de erros repetidos? Essa é a causa número cinco.
- As traduções estão sendo gravadas em
BepInEx/Translation/<lang>/Text/_AutoGeneratedTranslations.txt? Se esse arquivo está enchendo de traduções corretas que nunca aparecem na tela, o lado da rede está bem e o lado da exibição não está. - Aperte ALT+1 no jogo para abrir a janela do agregador de traduções. Se ela mostra as linhas que você está vendo, o hook enxerga essas linhas. Se continua vazia, o hook nunca as vê.
Essa última divisão — "traduzido mas não exibido" contra "nunca visto" — é a bifurcação da estrada. Tudo abaixo depende dela.
1. O jogo é uma build IL2CPP
O Unity distribui jogos em dois runtimes bem diferentes. O Mono mantém o C# do jogo como assemblies .NET comuns em <Game>_Data/Managed/, entre eles o Assembly-CSharp.dll, com nomes de tipos e de métodos intactos. O IL2CPP converte esse C# para C++ antes da hora e o compila em uma GameAssembly.dll nativa; o que sobra do sistema de tipos fica empacotado em <Game>_Data/il2cpp_data/Metadata/global-metadata.dat.
Um hook em tempo de execução precisa achar um método e substituí-lo. No Mono isso é um problema normal de reflexão. No IL2CPP não existe método gerenciado sobre o qual refletir — o código é nativo, e o único caminho de volta aos nomes, campos e endereços de método é interpretar o global-metadata.dat e reconstruir o layout. Isso é um loader completamente diferente, não uma configuração.
- Como saber em cinco segundos: uma
GameAssembly.dllao lado do executável do jogo, mais uma pastail2cpp_data, significa IL2CPP. Uma pastaManaged/cheia de DLLs significa Mono. - O IL2CPP exige o BepInEx na variante IL2CPP e a versão correspondente do XUnity.AutoTranslator compilada contra ele. A build para Mono simplesmente não carrega — ela não aparece no log, o que parece exatamente com "o plugin está quebrado".
- A largura de bits também importa. Um jogo de 64 bits precisa do loader de 64 bits. Um par incompatível falha do mesmo jeito silencioso.
- Alguns jogos trazem um arquivo de metadados impossível de interpretar. Empacotadores e camadas anti-adulteração criptografam ou reestruturam o
global-metadata.dat, e toda ferramenta que depende de lê-lo — o hook incluído — para por aí.
2. O plugin carrega e o texto nunca aparece
O plugin está no log, o endpoint foi inicializado, o _AutoGeneratedTranslations.txt está crescendo — e a tela continua igual. O hook está traduzindo uma string que o jogo depois joga fora, ou o jogo está definindo o texto por um caminho que o hook não intercepta.
TextGetterCompatibilityMode
Muitos jogos leem de volta o texto que acabaram de definir — para medi-lo, para concatenar algo, para compará-lo com outra coisa. Assim que o componente guarda uma string traduzida, essa leitura devolve a tradução, a lógica do próprio jogo passa a operar sobre um texto que ele não escreveu, e o resultado vai de uma linha que volta ao original até um layout que desmorona. O TextGetterCompatibilityMode, no AutoTranslatorConfig.ini, faz o getter devolver ao jogo a string original enquanto o jogador continua vendo a traduzida. Ele vem desligado por padrão porque custa trabalho a cada leitura, e é a primeira chave a testar quando o texto pisca, volta ao original ou se recusa a fixar.
A outra metade desse grupo é o texto que nunca é definido por uma API interceptada: um jogo que renderiza com o próprio motor de texto, que despeja caracteres direto em uma malha, ou que embute o diálogo em um sprite. Não existe configuração para isso — o ponto de interceptação não existe. Texto pintado na arte é um problema completamente à parte e precisa de tradução de imagens, não de um hook.
3. Só parte do texto é traduzida
Os menus traduzem, o diálogo não. Ou o diálogo traduz e todo botão continua em japonês. Isso é quase sempre um framework de UI que não está habilitado, porque o plugin faz hook em cada um separadamente e nem todos vêm ligados por padrão.
- Ligados por padrão: UGUI (a UI nativa do Unity), NGUI, TextMeshPro e UIElements (
EnableUGUI,EnableNGUI,EnableTextMeshPro,EnableUIElements). Juntos, cobrem a maioria dos jogos modernos, incluindo frameworks de visual novel como o Utage, que desenham através deles em vez de trazerem uma chave própria. - Desligados por padrão: IMGUI e o componente legado
TextMesh. O IMGUI é a GUI de modo imediato do Unity — ele redesenha a cada quadro, então dar hook nele significa traduzir a cada quadro, e ele fica desabilitado por desempenho, não por não funcionar. - As flags ficam no `AutoTranslatorConfig.ini` como
EnableIMGUI,EnableTextMeshe companhia. Coloque a do seu jogo emTruee reinicie. - Jogos Unity antigos e doujin japoneses são os casos típicos de IMGUI. Um jogo cujos menus parecem caixas cinzas simples com estilo padrão é uma pista forte.
Se habilitar tudo não mudar nada, o texto não está passando por um componente de texto do Unity — de volta à causa número dois.
4. Linhas longas são puladas, não traduzidas
O MaxCharactersPerTranslation vem em 200 por padrão. Qualquer coisa mais longa é pulada. Não é truncada, não é repetida, não é registrada de um jeito que você perceberia jogando — é pulada, então a linha aparece no idioma original e nada parece quebrado.
Essa é a causa que as pessoas caçam por mais tempo, porque a evidência é fraquíssima: quase todo o jogo traduz, e aí um parágrafo não. As visual novels são as vítimas de sempre — um bloco longo de narração ou um monólogo sem quebra de linha passa dos 200 caracteres com facilidade, e é justamente o texto que você mais queria traduzido.
Aumente o valor no AutoTranslatorConfig.ini e reinicie. Lembre que você também está aumentando o custo de cada requisição: os endpoints gratuitos têm os próprios tetos de comprimento por requisição e vão começar a rejeitar as que passarem deles individualmente, então um valor muito alto troca uma omissão silenciosa por um erro visível de endpoint. Algo entre 500 e 1000 dá conta da prosa comum de visual novel.
5. O endpoint falhou ou limitou a sua taxa
Os endpoints padrão do XUnity são serviços públicos e gratuitos de tradução, acessados do jeito que um navegador acessaria. Eles não têm contrato e mudam. Quando uma sequência de requisições falha seguida, o plugin desliga o endpoint pelo resto da sessão em vez de martelá-lo — uma decisão deliberada e boa, que também significa que tudo dali em diante fica silenciosamente sem tradução até você reiniciar o jogo.
- Procure a linha de desligamento no log. Se ela está lá, a correção é reiniciar mais mudar alguma coisa — não esperar mais.
- Diminua o ritmo da fila. O
MaxTranslationsQueuedPerSeconde as configurações de atraso existem porque são as rajadas que estouram os limites de taxa. Avançar rápido por uma visual novel manda centenas de requisições em segundos. - Troque de endpoint. Se um serviço gratuito está tendo um dia ruim, outro normalmente não está.
- Use um endpoint com chave. Uma chave real do DeepL ou de uma API paga elimina a categoria inteira do problema, ao custo de ser uma chave de API paga.
- Atualize o plugin. Quando o protocolo de um endpoint gratuito muda, a correção chega em forma de release. Rodar uma build de dois anos atrás contra um serviço que mudou é causa comum de "antes funcionava".
Bônus: o texto traduz e aparece como quadrados
Esse aqui nem é uma falha de tradução. O jogo veio com um atlas de fonte contendo exatamente os glifos de que o idioma original precisava, e o seu idioma de destino precisa de glifos que não estão ali, então cada caractere ausente é desenhado como um quadrado ou um vazio. O XUnity tem OverrideFont e OverrideFontTextMeshPro exatamente para isso. Note a assinatura: quadrados significam glifo ausente; caracteres `?` literais significam problema de codificação em algum ponto anterior da cadeia. São bugs diferentes, e a configuração de fonte só resolve o primeiro.
A ordem para investigar
- Confirme Mono ou IL2CPP procurando por
GameAssembly.dlle confirme que você instalou o loader correspondente. - Abra o
BepInEx/LogOutput.loge confirme que o plugin carregou e que um endpoint foi inicializado. - Aperte ALT+0 no jogo para abrir a janela do próprio plugin — se nada aparecer, o plugin não carregou. ALT+1 abre o Translation Aggregator: vazio significa que o hook nunca vê o texto; preenchido significa que vê.
- Se o hook vê e a tela não muda, ligue o
TextGetterCompatibilityMode. - Se só parte do jogo traduz, habilite o IMGUI e o TextMesh legado.
- Se linhas longas específicas continuam sem tradução, aumente o
MaxCharactersPerTranslationa partir do padrão de 200. - Se tudo parou no meio da sessão, procure a linha de desligamento do endpoint e reinicie com uma fila mais lenta ou outro endpoint.
Quando um hook é o formato errado para o serviço
Todas as falhas acima levam à mesma raiz: um hook em tempo de execução só traduz o texto que ele está presente para interceptar. Se o jogo não define a string por uma API que o plugin conhece, ou se o texto foi desenhado antes de o plugin carregar, ou se o runtime não expõe o método para hook, não há nada a configurar. A ferramenta está fazendo o trabalho dela corretamente e o texto simplesmente está fora de alcance.
A alternativa estrutural é trabalhar nos arquivos em vez de no quadro. Uma ferramenta em nível de arquivo abre os próprios assets do jogo, tira as strings de lá, traduz e escreve uma cópia traduzida do jogo — então o texto já está no idioma de destino antes de o motor sequer carregá-lo. Sem hook, sem ponto de interceptação, sem flag por framework, e o limite de caracteres é o que o formato aguentar. É isso que o RuneTranslate faz, no Unity e em outros 16 motores e formatos.
As contrapartidas são reais e vão para o outro lado. Uma ferramenta em nível de arquivo só alcança texto que está nos arquivos — no Unity, isso significa TextAssets, campos de string de MonoBehaviour, scripts de StreamingAssets, tabelas de localização e asset bundles, incluindo bundles Addressable criptografados em AES. Ela exige uma etapa de exportação antes de jogar, em vez de traduzir enquanto você joga. E não pode fazer nada com o texto que o jogo monta em tempo de execução a partir de fragmentos. O Unity é um motor de melhor esforço exatamente por isso: o que cada jogo externaliza varia enormemente, e abrir o projeto é o que diz qual é o seu caso.
- Texto compilado no código C# é o limite duro. Em builds Mono, o RuneTranslate lê os literais de string do assembly do jogo com um sidecar embutido, filtrando pelo que o ponto de chamada faz com eles, para nunca traduzir um nome de cena ou um parâmetro de animator. Em builds IL2CPP, o código compilado fica fora de escopo.
- Texto em assets no IL2CPP funciona, porém. Campos de string de componentes são lidos no IL2CPP reconstruindo as informações de tipo a partir dos metadados do jogo — o mesmo
global-metadata.datde que o hook precisa, usado para outro fim. - Ele lê a saída do próprio XUnity. Se você já tem um
_AutoGeneratedTranslations.txtpreenchido, o RuneTranslate interpreta esse arquivo e pode traduzir os valores dele, sem mexer nas chaves. O trabalho que você já fez não é jogado fora. - As fontes são tratadas na exportação, injetando um asset de fonte de fallback no jogo para que um idioma de destino que a fonte original nunca cobriu ainda seja renderizado.
Nove provedores, três deles sem precisar de chave de API nenhuma — Google, DeepL gratuito e os modelos Classic/Next-gen do DeepL —, mais a API do DeepL, OpenAI, Anthropic, DeepSeek, qualquer endpoint compatível com OpenAI e um modelo local via Ollama ou LM Studio. O tier gratuito desbloqueia todos os motores e todos os provedores; ele limita a vazão e mantém um projeto por vez. Windows 10/11, ou Linux e o Steam Deck sob Wine ou Proton. É preciso um login gratuito no Patreon na primeira execução. A saída é uma build traduzida jogável que fica com você.
Nenhuma das duas abordagens é certa universalmente. Um jogo cujo script inteiro está em uma tabela JSON empacotada é um trabalho em nível de arquivo e sempre foi. Um jogo que monta o diálogo em código em tempo de execução é um trabalho de hook e sempre será. Saber qual dos dois você tem em mãos é a maior parte do serviço.
Para onde ir depois
- Como traduzir jogos Unity — o passo a passo completo, incluindo o que o Unity externaliza e o que não.
- A página do motor Unity — os formatos suportados e os limites atuais em um só lugar.
- RuneTranslate vs. XUnity.AutoTranslator — as duas abordagens lado a lado, com os casos que cada uma vence.
- Escolhendo um provedor de tradução — quais lidam bem com prosa japonesa e quais não custam nada.
- Noções básicas de glossário — mantendo nomes de personagens e terminologia consistentes em um script inteiro.
- Todos os motores suportados — se o jogo acabar não sendo Unity, afinal.
Pronto para experimentar o RuneTranslate?
O plano gratuito libera todos os motores + todos os provedores de tradução. O plano Supporter ($3/mo) libera velocidade total.
Baixar para Windows
