Localização de jogos no Unreal Engine 4

Preparar um jogo para localização é uma parte importante do desenvolvimento do jogo.

Estamos trabalhando no jogo " Cat Movies! " No Unreal Engine 4. Essa é uma estratégia econômica na qual há muito texto, e planejamos traduzi-lo para vários idiomas. Como muitos outros (mas isso não é exato, e espero que não seja assim), decidimos adiar o estágio de configuração da localização para iterações de desenvolvimento posteriores e, como se viu, em vão.

A localização no UE4 é implementada de maneira inteligente e, se você se lembrar de que todo o texto que será traduzido é suficiente para armazenar nos campos Ftext (Texto em Blueprint'ah), em geral, não há problema em obter texto do jogo. É suficiente abrir o Painel de Localização, apertar alguns botões - e pronto.

E, apesar da simplicidade dessa ação, ainda encontramos vários problemas, por causa dos quais tivemos que cavar uma parte do código.

Atualizado em 10.16.19: Formatação de texto.

Como armazenar texto


Os caras da Epic Games simplificaram a montagem do texto ao máximo, reduzindo tudo a um clique e mais traduções.

Tudo funciona de maneira muito simples - para localização, é usado o tipo de dados FText (Text in Blueprints), no qual o texto é salvo, e esse texto é coletado posteriormente pelo sistema de localização e fornecido para tradução.

Como isso funciona?

O FText não é um tipo de dados padrão que armazena dados em si. Obviamente, ele armazena dados em si, mas não os dados que esperamos.

FText é um ponteiro. Indica em qual tabela o texto está armazenado. Ou seja, quando atribuímos um texto a uma variável desse tipo, o texto é armazenado em uma tabela virtual e a própria variável agora armazena o nome da tabela e a chave pela qual encontrar o texto nessa tabela.

Assim, verifica-se que o texto em si é armazenado em outro lugar (não consideraremos as sutilezas de implementá-lo, pois não estamos particularmente interessados ​​nele) e, ao alternar a localização para o endereço desejado, o texto é substituído (bem ou Eu quero pensar assim).

imagem

Quando a coleta de texto é iniciada, o sistema de localização coleta todas as variáveis ​​de texto de todos os modelos, widgets e tabelas e lança uma lista enorme de texto que pode ser exportado para * .po e traduzido.

Nosso jogo possui um grande conjunto de widgets através dos quais o jogador controlará quase toda a jogabilidade. Temos muitos nomes (por exemplo, departamentos ou estágios de criação de filmes ou algumas habilidades, bônus etc.) que são usados ​​em vários widgets que não têm nenhuma relação entre si. Existem descrições de alguns objetos (por exemplo, uma descrição de bônus), e isso também é usado mais de uma vez em vários widgets não relacionados.

E aqui começa a dificuldade. Se reescrevermos os nomes dos departamentos em cada widget, em algum momento de um dos widgets, o nome dos departamentos será digitado incorretamente. Essa questão é complicada pelo fato de que as próprias "descrições" (por exemplo, a descrição do departamento) em um grande número de caracteres são difíceis de rastrear, de modo que são as mesmas em todos os lugares (naturalmente, não o fizemos). Ainda mais divertido é que temos a maioria dos widgets usados ​​como modelo no qual os dados de várias fontes voam e, com base em qual fonte, os nomes e textos dentro do código são alterados.

Facilitamos nossa tarefa criando uma Tabela de Dados, na qual começamos a armazenar dados de tipos específicos. Por exemplo, uma tabela de departamento que contém o nome, descrição, nível máximo, número de funcionários por nível, etc. etc.
Parece que era possível me debruçar sobre isso, mas havia uma dificuldade no fato de os dados na tabela serem alterados constantemente, algo era reescrito, que era excluído à medida que o código crescia, e havia momentos em que toda a tabela travava, e tivemos que reverter, retirar dados, retorne ao estado atual e insira os dados perdidos novamente.

Tudo ficou muito mais triste quando decidi entrar na localização e, finalmente, tentar entrar e sair para entender se estamos fazendo tudo certo.

Puxei todo o texto do jogo e percebi que no código, apesar de tentarmos evitar a repetição, havia um grande número de elementos repetidos do texto.

A tradução é uma coisa humana. Se houver uma oportunidade de cometer um erro, as pessoas necessariamente cometerão um erro. E para evitar isso ou pelo menos minimizá-lo, você precisa reduzir todos os textos para um único modelo. Ou seja, a saída em algum lugar em um só lugar, de onde o texto será obtido em todas as partes do código. E que será traduzido apenas uma vez para minimizar os riscos de erros. Parece que você pode usar o DataTable, mas existem vários problemas - para salvar apenas os nomes de algo, precisamos criar tabelas inteiras que armazenem esses nomes.

Após vasculhar a documentação da Epic Games, voltei minha atenção para as Tabelas de Cordas (a seguir denominadas "tabelas de cordas"). Descobriu-se que esta é uma opção ideal - armazenar o texto em uma tabela separada especial para textos, que foi criada apenas para ser conectada às variáveis ​​do FText. Ou seja, podemos criar uma tabela que armazene o texto em si. E podemos conectar esse texto a qualquer variável - seja uma variável na tabela de dados, uma variável no widget, uma variável no código - tudo se resume a um local em que o texto é armazenado.

As tabelas de cadeias permitem evitar a repetição de texto em um projeto várias vezes um pouco mais do que completamente, evitando erros.

As tabelas de sequência são criadas no mecanismo, assim como as tabelas de dados na seção diversa:

imagem

É muito fácil preencher - cada nova linha deve ter uma chave única que você precisa inventar. E o próprio texto já pode ser qualquer. Além disso, na tabela você pode especificar um nome diferente para o espaço de texto do nome da tabela, mas, em nossa experiência, isso não é necessário.

Depois que a tabela de cadeias é criada, o texto agora pode ser conectado à variável FText:

imagem

imagem

Assim, reduzimos o texto para uma tabela de linha única, da qual é muito fácil extrair. Para obter este menu de configurações de texto, basta clicar na seta para baixo ao lado da variável de texto.

Localização


Agora só precisamos coletar todo o texto e começar a trabalhar com ele. Para fazer isso, precisamos iniciar o Painel de Localização e iniciar as configurações de localização. Você pode executar a tabela no menu Janela-> Painel de Localização.

E antes de abrir algo como esta janela:

imagem

Nesta janela, você deve especificar a meta (módulo) a partir da qual o texto será extraído. No nosso caso, este é um jogo - Jogo.

Em seguida, você precisa especificar onde exatamente o texto será extraído no módulo. No nosso caso, esses são apenas embotamentos, pois não armazenamos texto nos cursos. Portanto, precisamos especificar apenas “Gather from Packages” e indicar em quais pastas e quais arquivos devemos considerar para pesquisar textos.

Também precisamos indicar quais idiomas serão usados ​​para tradução e qual idioma será nativo (principal). Eu recomendo se você escrever e falar russo - indique o idioma russo (ou qualquer outro idioma principal). Isso se deve ao fato de que, se você não conhece bem o inglês e o indica como principal, complica sua tradução para o inglês de "inglês". Portanto, é melhor indicar seu idioma com antecedência como o principal e escrever todos os textos em seu próprio idioma, para que mais tarde você possa facilitar as traduções para si e para os outros.

Também no UE4, há uma grande oportunidade de criar traduções diretamente no mecanismo, sem exportar textos para programas de terceiros. Para fazer isso, você precisa coletar todo o texto relevante no jogo pressionando o botão número 1. E, em seguida, execute o editor (botão número 2):

imagem

Uma janela para editar a tradução para o idioma necessário é exibida.

Assembléia


Ao montar um projeto, você deve especificar os idiomas que devem ser incluídos neste assembly, bem como o conjunto de idiomas que seu projeto deve suportar.

imagem

No nosso caso, o Suporte à Internacionalização está definido como Todos. Ou seja, nosso projeto suportará todos os tipos de idiomas, de hieróglifos complexos a simples letras em inglês. Em geral, existem 5 pacotes:

  • Inglês (inglês puro).
  • EFIGS (inglês, francês, italiano, alemão e espanhol)
  • EFIGSCJK (o mesmo que acima + chinês, japonês e coreano)
  • CJK (chinês, japonês e coreano).
  • Todos (todos os idiomas).

No entanto, nos casos em que cada byte no projeto é importante (o pacote Todo pesa 15 MB e EFIGS 2 MB), você deve prestar mais atenção em qual pacote precisa escolher.

Comutação de Localização


A troca de texto ocorre no tempo de execução, ou seja, você não precisa reiniciar o jogo, não precisa se preocupar com a otimização da troca - tudo é feito de maneira fácil e simples através do método " SetCurrentCulture ", onde você precisa indicar com o texto para qual idioma deseja mudar.

imagem

E aqui há alguns obstáculos. O fato é que diferentes países têm seus próprios idiomas, por exemplo, existe o principal idioma russo (ru), mas existem bielorrusso (ru-BY), cazaque (ru-KZ), moldavo (ru-MD), ucraniano (ru) -UA) idiomas que se enquadram no ramo do idioma russo. Portanto, ao escolher um idioma que não seja o principal, é necessário considerar e indicar o idioma correto. Se você selecionar apenas o principal, ao mudar, basta especificar "ru".

imagem

Adicionando outros dados ao texto no Blueprint.


Se colchetes forem indicados no próprio texto e o nome dos dados estiver neles, no futuro, você poderá usar a substituição desses mesmos dados no texto.
Por exemplo: "Gostaria de aprender a tecnologia {Tech_Name}?"
Além disso, no BP, você pode usar o nó "Format Text", que levará em conta o texto em si e quais parâmetros são indicados lá, além de criar pinos adicionais para conectar esses dados:
imagem

Agora informações adicionais serão incorporadas ao texto, que podem ser corrigidas sem corrigir o próprio texto. Por exemplo, você pode inserir os nomes de departamentos ou tecnologias, especificar níveis ou algo mais.

Conclusão


Depois de reunir todas essas informações, percebi que desde o início não abordamos corretamente a criação de texto no jogo e fizemos muito trabalho desnecessário. Obviamente, não reformulamos o código por meses, mas gastamos um máximo de 1,5 horas nisso, mas seria bom conhecer os princípios de localização no UE4 com antecedência e levá-los em consideração ao criar a arquitetura do projeto.

O mesmo vale para Salvar e carregar nos jogos. Isso acabou não sendo uma tarefa tão fácil no contexto da estratégia, onde tudo deve ser consertado onde está / se encontra / tem um certo estado. Mas vou escrever sobre isso em outro momento. E agora você pode continuar assistindo nosso jogo em nosso grupo =)

Source: https://habr.com/ru/post/pt470205/


All Articles