How to Translate Your Game Using the Unity Translation Package
Welcome to the wild world of localization, where Veggie Gladiators are about to prove that vegetables aren’t just for salads, but for speaking multiple languages too! Picture this: your game is a hit in Tokyo, and suddenly the Veggie Gladiators have to fight in a sushi bar. Without localization, they’ll be lost in translation faster than a potato in a fruit salad. So, let’s arm our Veggie Gladiators with languages and take over the global gaming arena, one veggie at a time! By Ben MacKinnon.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How to Translate Your Game Using the Unity Translation Package
30 mins
- Getting Started
- Your First Translation
- Installing the Localization Package
- Adding Translation
- Building the Menu
- Adding a Translation Option Menu
- Setting Up Localization Manager
- Localization Settings
- Connecting Everything
- Finding Translations
- Importing Localization Files
- Translating Dialogue
- Translating the Interaction System
- Translating NPC Names
- Translating Questions
- Habla Español?
- Where to Go From Here?
Importing Localization Files
Open the Project window and navigate to the RW ▸ Localization folder. Right-click this folder and choose Create ▸ Localization ▸ Google Sheets Service. This will create a new asset, which you can leave with the default name.
Fill in the details for the Google Sheets Service:
- Application Name: VeggieGladiators
- Authentication: API Key
-
API Key:
AIzaSyAReIYky0KA6RWtH3ESG5CGdCHMjutSX9w
You’ll use this service to import all the dialogue translations. Open the Localization Tables window again if it isn’t still open – Window ▸ Asset Management ▸ Localization Tables. Switch to the New Table Collection tab, and create a new table called DialogueTable. Save it in a new folder at RW ▸ Localization ▸ Game.
Select the DialogueTable asset, and under Extensions, add a Google Sheets Extension.
Fill in the new options with the following values:
- Sheets Service Provider: Select the file you set up in the last section.
-
Spreadsheet ID:
1BXL7r1BX2PzyhSyg9zP11Vys-u4ryIpeWK9Cm3S3g2E
-
Sheet ID:
2022142460
With the spreadsheet ID filled in, the extension should recognize the referenced file, and you should see the DialogueTable option under Select Sheet.
Under the Mapped Columns, click the + button and select Add Default Columns. This is how you connect the data in the Google Sheet to the data in the String Table Collection. By default, it will create a Key Column and as many Locale Columns as you have Locales set up. The default values set here match what is provided in the Google Sheet already.
With all this setup, you’re now just a single click away from having ALL the translation strings for every dialogue in the DiningHall scene! Click Pull and watch the DialogueTable magically get populated.
You can see that the window also has buttons for Push, Push Selected and Pull Selected. As updates are made to either the Table Collection or the Google Sheet, you can keep the two in sync by pushing from Unity and pulling from Google.
Translating Dialogue
If you didn’t try walking around and triggering all the dialogue earlier, you should definitely try it now. Notice that some of the dialogues have multiple lines, some have a bit of back-and-forth conversation, and some even require some user input to progress.
Now that you have all the translated strings available, you need to actually bring those translations in at runtime. Fortunately, all the dialogues have been built into a system that can easily be updated to support translations!
The dialogues are all stored in the folder RW ▸ Conversations as Scriptable Objects. Select the Bored Warrior, and you can see an example of a single line of dialogue.
The Conversation scriptable object just holds an array of DialogueLines. The DialogueLine class consists of four fields:
- A string for the speaker.
- Another string for the text.
- A Bool to determine if it’s a question.
- A DialogueQuestion for when it is a question.
Strings mean one thing. Translations!
Open RW ▸ Scripts ▸ Dialogue ▸ DialogueLine in your script editor. The first thing to change is the text variable. Currently, it’s a string with a TextArea attribute.
[TextArea(2, 3)]
public string text;
Add a new import to the top of the file to bring in the localization options:
using UnityEngine.Localization;
Next, remove the TextArea attribute, and add a new field:
public LocalizedString localizedString;
Finally, change the text
field to make it an accessor to the GetLocalizedString()
method of localizedString
. The class should look like this in the end:
using System;
using UnityEngine;
using UnityEngine.Localization;
[Serializable]
public class DialogueLine
{
public string speaker;
public LocalizedString localizedString;
public string text => localizedString.GetLocalizedString();
public bool thisIsAQuestion;
public DialogueQuestion dialogueQuestion;
}
Save the script and go back to Unity. Notice the Inspector view of the Bored Warrior dialogue has updated to a familiar view from the early steps of this tutorial.
In the Localized String option, search for and select the Bored Warrior string from the DialogueTable.
This conversation is now translated! Go through each of the conversations and pick the key that matches the name of the conversation. Where a conversation has more than one line of dialogue, there’ll be a Key2 etc. for additional lines.
You can play the game now, switch the language to German in the Title scene, start a new game and walk around to initiate some conversations. You’ll see that all the NPCs respond to you in German, but there are still a couple of things missing.
Translating the Interaction System
First is the prompt that appears when you get close to any of the NPCs. These are set up around the scene, but fortunately, you don’t need to edit the scene to add translations for them.
Open the InteractableObject script. Similar to the DialogueLine script, it has a few simple fields and an abstract method you don’t need to worry about.
public abstract class InteractableObject : MonoBehaviour
{
public string interactionName;
public string interactionVerb;
public bool canBeInteractedWith = true;
public abstract void Interact(PlayerAvatar playerAvatar);
}
First, add a new using
to the top of the script.
using UnityEngine.Localization.Settings;
Next, change the two public string
s to [SerializeField] private string
s instead.
[SerializeField] private string interactionName;
[SerializeField] private string interactionVerb;
Finally, add two new public accessor strings that use LocalizationSettings.StringDatabase.GetLocalizedString
to return the translated value of the private strings.
public string InteractionName => LocalizationSettings.StringDatabase.GetLocalizedString(interactionName);
public string InteractionVerb => LocalizationSettings.StringDatabase.GetLocalizedString(interactionVerb);
Each of the interactionName
and interactionVerb
values are already present as keys in the Dialogue Table, so these two lines will look up the table for the given keys and return the translated value.
The final script will look like this:
using UnityEngine;
using UnityEngine.Localization.Settings;
public abstract class InteractableObject : MonoBehaviour
{
[SerializeField] private string interactionName;
[SerializeField] private string interactionVerb;
public bool canBeInteractedWith = true;
public string InteractionName => LocalizationSettings.StringDatabase.GetLocalizedString(interactionName);
public string InteractionVerb => LocalizationSettings.StringDatabase.GetLocalizedString(interactionVerb);
public abstract void Interact(PlayerAvatar playerAvatar);
}
Save the script and go back to Unity. You should notice now that you have an error in the console. That’s because the InteractionSystem was referencing those two strings that you just made private.
Open the RW ▸ Scripts ▸ Interaction ▸ InteractionSystem script and find the error at line 81. Change the references to point at your new public variables:
interactionText.text = interactionTarget.InteractionVerb + " " + interactionTarget.InteractionName;