Voltar para o Blog
Quest Log

Traduzir Jogo na Unity com o Pacote Localization

Menu de jogo com o mesmo botão escrito em português e em inglês, ligados por uma tabela de tradução flutuante

Unity Localization passo a passo: Locales, String Tables, Localize String Event no TextMeshPro, seletor de idioma e Smart Strings com variável, no Unity 6.3.

Ferramenta:UnityC#

Traduzir Jogo na Unity com o Pacote Localization

O Unity Localization é o pacote oficial para traduzir um jogo na Unity: você cria os idiomas (Locales), guarda os textos em String Tables e liga cada texto da tela a uma chave com o componente Localize String Event. Aqui você traduz um jogo pequeno para português do Brasil e inglês, monta um seletor de idioma no menu e faz um contador de moedas que muda a frase conforme o número, tudo no Unity 6.3 LTS.

A versão do pacote que o manual do Unity 6.3 lista como liberada para o editor 6000.3 é a 1.5.13 (conferida em outubro de 2026). Se você abrir a documentação "latest" do pacote, ela pode cair numa versão mais nova, feita para outro editor. Siga a da sua versão.

O que o pacote Localization da Unity faz

Sem pacote, a tradução costuma virar um Dictionary<string, string> caseiro e um if (idioma == "en") espalhado pelo projeto. Funciona até o terceiro menu. O pacote resolve as partes chatas:

  • Locales: cada idioma é um asset, com código padrão (pt-BR, en).
  • String Tables: planilhas de chave e tradução, uma coluna por idioma, editáveis numa janela própria e exportáveis para CSV ou Google Sheets quando entra um tradutor.
  • Componentes de ligação: o Localize String Event troca o texto sozinho quando o idioma muda, sem você escrever código para cada label.
  • Smart Strings: frases com variável e plural, como "Você tem 3 moedas".
  • Asset Tables: trocar imagem, áudio ou fonte por idioma (útil para dublagem ou para fontes de idiomas asiáticos).

Antes de pôr a mão no pacote, vale decidir se e para quais idiomas traduzir. Essa é uma decisão de negócio, e o post sobre quais idiomas traduzir no seu jogo cobre esse lado. Aqui o foco é a execução técnica.

Instalando e criando Locales

  1. Window > Package Management > Package Manager, aba Unity Registry, procure Localization e clique em Install.
  2. Edit > Project Settings > Localization e clique em Create para gerar o asset de Localization Settings. Salve numa pasta Localization/.
  3. Na mesma tela, clique em Locale Generator. Marque English (en) e Portuguese (Brazil) (pt-BR) e clique em Generate Locales. Escolha a pasta e pronto: dois assets de Locale aparecem.
  4. Em Locale Selectors, a lista define como o jogo escolhe o idioma ao abrir. Adicione o Player Pref Locale Selector no topo, para o jogo lembrar a escolha do jogador. Abaixo dele, deixe o System Locale Selector (idioma do sistema) e, por último, o Specific Locale Selector apontando para o idioma padrão.

A ordem importa: o pacote tenta cada seletor de cima para baixo e usa o primeiro que devolver um idioma. Com o Player Pref em cima, quem já escolheu idioma no menu não é sobrescrito pelo idioma do Windows.

String Tables e chaves

  1. Window > Asset Management > Localization Tables.
  2. New Table Collection, tipo String Table Collection, marque os dois Locales, nome UI, Create.
  3. Clique em Add New Entry para cada texto. Na coluna Key, use nomes com prefixo de tela: menu.jogar, menu.opcoes, menu.sair, hud.moedas. Preencha as colunas English (en) e Portuguese (Brazil) (pt-BR).

Três regras que poupam retrabalho:

  • Chave descreve o lugar, não o texto. menu.jogar sobrevive a uma mudança de "Jogar" para "Começar". Uma chave jogar não.
  • Uma tabela por área. UI, Dialogos, Itens. Uma tabela gigante única fica lenta de editar e difícil de mandar para tradutor.
  • Nunca monte frase concatenando pedaços. "Você tem " + n + " moedas" quebra em idioma com outra ordem de palavras. Use Smart Strings, mais abaixo.

Ligando textos com Localize String Event

Crie o texto pelo GameObject > UI > Text - TextMeshPro. Depois:

  1. No objeto de texto, Add Component > Localize String Event.
  2. No campo String Reference, escolha a tabela UI e a chave menu.jogar.
  3. Em Update String (), clique no +, arraste o próprio objeto de texto para o campo e escolha TextMeshProUGUI > text na lista de propriedades dinâmicas (a seção do topo, sem valor fixo).

Pronto: quando o idioma muda, o componente busca a tradução e chama o evento, que escreve no text do TextMeshPro. Em vários casos o atalho de clicar com o botão direito no cabeçalho do componente de texto e escolher Localize faz esses três passos de uma vez; se ele não aparecer, o caminho manual acima sempre funciona.

Para testar sem dar build, rode a cena e use o dropdown de idioma que aparece na Game View. Se ele não aparecer, ative em Edit > Preferences > Localization.

Seletor de idioma no menu

O menu precisa listar os idiomas disponíveis e trocar quando o jogador escolhe. O ponto crítico é esperar o pacote inicializar: ele carrega as tabelas de forma assíncrona, e acessar SelectedLocale antes disso devolve valor incompleto.

Arquivo LanguageSelector.cs:

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;

public class LanguageSelector : MonoBehaviour
{
    [SerializeField] private TMP_Dropdown dropdown;

    private IEnumerator Start()
    {
        yield return LocalizationSettings.InitializationOperation;

        List<Locale> locales = LocalizationSettings.AvailableLocales.Locales;
        List<string> labels = new List<string>();
        int selectedIndex = 0;

        for (int i = 0; i < locales.Count; i++)
        {
            labels.Add(locales[i].LocaleName);
            if (locales[i] == LocalizationSettings.SelectedLocale)
            {
                selectedIndex = i;
            }
        }

        dropdown.ClearOptions();
        dropdown.AddOptions(labels);
        dropdown.SetValueWithoutNotify(selectedIndex);
        dropdown.onValueChanged.AddListener(OnLanguageChanged);
    }

    private void OnDestroy()
    {
        dropdown.onValueChanged.RemoveListener(OnLanguageChanged);
    }

    private void OnLanguageChanged(int index)
    {
        LocalizationSettings.SelectedLocale = LocalizationSettings.AvailableLocales.Locales[index];
    }
}

Por que assim:

  • IEnumerator Start. A Unity aceita Start como corrotina, e o yield return na operação de inicialização segura o código até as tabelas estarem prontas.
  • Sem PlayerPrefs manual. O Player Pref Locale Selector configurado no começo já grava a escolha quando SelectedLocale muda e a lê na próxima abertura.
  • LocaleName como rótulo. Ele mostra o nome configurado no asset do Locale. Renomeie os assets para "Português (Brasil)" e "English": cada idioma escrito nele mesmo, porque quem não lê português precisa achar o próprio idioma sem ajuda.

Ligar um menu inteiro (idioma, volume, resolução, controles) e fazer tudo isso sobreviver à troca de cena e ao build é onde o projeto pessoal costuma emperrar: cada tela funciona sozinha, o conjunto não. No curso de Unity esse menu de opções é construído dentro de um jogo completo, do primeiro protótipo ao build publicado.

Curso de Unity
Quer fazer seu primeiro jogo na Unity?

No curso de Unity 6 da CursoGame.Dev você vai do zero ao primeiro jogo, com um desafio prático em cada level e suporte individual no WhatsApp quando travar.

Conhecer o curso de Unity
Suporte no WhatsAppAcesso vitalícioGarantia de 7 dias

Texto com variáveis e plural (Smart Strings)

O HUD quer mostrar "Você tem 1 moeda" e "Você tem 5 moedas", e em inglês "You have 1 coin" e "You have 5 coins". Concatenar não serve. Use uma Smart String:

  1. Na janela de tabelas, na entrada hud.moedas, marque a opção Smart.
  2. Em pt-BR escreva: Você tem {moedas} {moedas:plural:moeda|moedas}
  3. Em en escreva: You have {moedas} {moedas:plural:coin|coins}

O formatador plural escolhe a forma pelas regras de plural do idioma ativo. Teste o zero nos dois idiomas, porque línguas tratam o zero de forma diferente e você pode preferir uma frase específica ("Nenhuma moeda").

Agora o valor vem do jogo. No pacote 1.5, o LocalizedString funciona como um dicionário de variáveis locais: você adiciona um IntVariable com o mesmo nome do placeholder e, quando muda o Value, o texto se atualiza sozinho.

Arquivo CoinCounterText.cs:

using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Components;
using UnityEngine.Localization.SmartFormat.PersistentVariables;

public class CoinCounterText : MonoBehaviour
{
    private const string VariableName = "moedas";

    [SerializeField] private LocalizeStringEvent stringEvent;

    private IntVariable coins;

    private void Awake()
    {
        LocalizedString reference = stringEvent.StringReference;

        if (reference.TryGetValue(VariableName, out IVariable existing) && existing is IntVariable intVariable)
        {
            coins = intVariable;
        }
        else
        {
            coins = new IntVariable { Value = 0 };
            reference[VariableName] = coins;
        }
    }

    public void SetCoins(int amount)
    {
        coins.Value = amount;
    }
}

O objeto do HUD tem o Localize String Event apontando para hud.moedas, e o seu script de moedas chama SetCoins sempre que o jogador pega uma. Também dá para criar a variável pelo Inspector, na seção Local Variables do String Reference; o código acima reaproveita a que existir.

Erros comuns: texto não troca e fonte sem acento

O texto não muda quando troco o idioma. Quase sempre é o evento Update String sem destino ou apontando para a opção estática do text (a da parte de baixo da lista, com campo de valor). Tem que ser a dinâmica, que recebe a string do evento.

Aparece "No translation found". A chave existe numa tabela, mas a coluna daquele idioma está vazia. Preencha, ou configure um fallback no asset do Locale (campo Fallback) para cair no inglês.

O seletor mostra a lista vazia. O código leu AvailableLocales antes da inicialização. Confira o yield return LocalizationSettings.InitializationOperation.

Acentos e "ç" viram quadrados. O Font Asset do TextMeshPro não tem esses glifos. Abra Window > TextMeshPro > Font Asset Creator, escolha a fonte, em Character Set use Custom Range com 32-126,160-255 (ASCII imprimível mais o Latin-1, com todos os acentos do português) e gere de novo. A alternativa é deixar o Font Asset com Atlas Population Mode em Dynamic, que adiciona os caracteres que faltam em tempo de execução, desde que o arquivo da fonte original vá junto no build. Para chinês ou japonês, use um Font Asset por idioma trocado por Asset Table.

Funciona no editor e não no build. As tabelas são carregadas pelo Addressables. Se o build foi feito sem o conteúdo do Addressables gerado, os textos não aparecem. Rode o build pelo File > Build Profiles normal, que inclui esse passo por padrão, e confira se nenhuma configuração desligou o build do Addressables junto com o Player.

Próximo passo

Traduza o menu principal e o HUD de um projeto seu, deixe o diálogo para depois e teste o build com o Windows em inglês para ver o System Locale Selector agindo. Se você também trabalha com Godot ou está escolhendo engine, compare com o guia de localização e tradução na Godot: a ideia de chave mais tabela é a mesma, e entender as duas deixa claro o que é conceito e o que é detalhe de ferramenta.

Perguntas frequentes

Qual versão do pacote Localization usar no Unity 6.3?

O manual do Unity 6.3 lista o com.unity.localization 1.5.13 como a versão liberada para o editor 6000.3. Instale pelo Package Manager, na aba Unity Registry, e confira se o número bate com o da documentação da sua versão de editor.

O que é uma String Table na Unity?

É a tabela onde ficam os textos traduzidos. Cada linha tem uma chave (por exemplo, menu.jogar) e uma coluna por idioma. Os componentes da cena guardam só a referência à chave, e o pacote busca o texto do idioma ativo.

Como trocar o idioma do jogo por código na Unity?

Espere o LocalizationSettings.InitializationOperation terminar e atribua um dos itens de LocalizationSettings.AvailableLocales.Locales ao LocalizationSettings.SelectedLocale. Todos os textos ligados por Localize String Event atualizam sozinhos.

Por que as letras com acento aparecem como quadrados no TextMeshPro?

O Font Asset do TextMeshPro foi gerado sem esses caracteres. Gere de novo com um conjunto que inclua o Latin-1 (faixa 32 a 255) ou use um Font Asset dinâmico, que adiciona os glifos que faltam em tempo de execução.