I made a game, and all is well. Except I've been asked to provide translated versions. I can't figure out ANY sort of workflow that will be maintainable for this... looking for advice!
I'm not new to localization, and making/maintaining string tables isn't the problem. The problem is finding a way to integrate the tables into the editor GUI so that I can still see the original strings easily (and not just the string's IDs).
Many of the strings in the game were typed into the Unity editor. For instance, "talk trees" were implemented as simple arrays of nodes, each node containing some strings and some flags. Very convenient for development. But now I can't get the strings out of the editor.
One reasonable workflow would be to replace each of those strings with a token -- for instance the string "Hi there" might get replaced by "#142". That would give me the info to look up string #142, which would be "Hi there" in the appropriate language. But I need to be able to see the ORIGINAL string in the editor -- seeing just "#142" is completely useless if I need to fix bugs or make improvements to the game.
I've tried writing a plugin that keeps track of the currently-active text field in the editor -- that way the plugin could see that it says "#142" and display "#142 = 'Hi there'" in a little window. But I can't get that to work.
I've tried... well, I've tried all sorts of things. But I'd love to hear somebody who has a workflow that works... and that doesn't make the editor completely useless for future editing!
You could replace each string with a serializable structure (implemented as a class, since Unity doesn't like serializing structs), something like this (C#):
[System.Serializable]
public class LocalizedString
{
[SerializeField]private int _ID;
#if UNITY_EDITOR
[SerializeField]private string _Text;
#endif
public string Text
{
get { return LocalizationSystem.GetText(_ID); }
}
public override string ToString()
{
return Text;
}
}
Inside your components instead of using strings, you would use LocalizedStrings:
public LocalizedString MyString;
When you access the text from code, you would use MyString.Text instead of simply MyString. You need to implement the LocalizationSystem.GetText to do your string table lookup.
The _Text field is only needed in the editor, so it can be compiled out in the final build to save some space. Both _Text and _ID are private, but marked for serialization, so your client code can't peer into internal details it doesn't need to know about.
The ToString override lets you dump MyString into String.Format or similar methods without having to reference the Text property, and also should make it show up nicely in a debugger.
You could go beyond this to augment the editor to understand the currently selected language, and have an editor feature to iterate through your scene, replacing the _Text field of all LocalizedStrings with the text string from your language of choice.
Disclaimer: I haven't done this myself, but I've used string localization tables extensively in a former life and will need to do so again at some point soon. Let me know what you come up with, I'd be interested to hear how it goes.