Usage / Keybinds / BLOC Format / FAQ / How It Works
Complete API documentation for PicoShot Localization system.
- Initialization
- Getting System Language
- Enumerating Available Languages
- Getting Native Language Names
- Setting Language
- Text Retrieval
- Bind Functions (Components)
- Events
- Advanced Usage
The localization system initializes automatically on startup. No manual initialization is required.
// Check if initialized
if (LocalizationManager.IsInitialized)
{
// System is ready
}
// Manual initialization (optional, system auto initialize itself)
LocalizationManager.Initialize();Detect the user's system language and convert it to a supported language code.
// Get system language as ISO code (e.g., "en", "es", "ja")
string systemLanguage = LocalizationManager.DetectSystemLanguage();
// Direct conversion from Unity's SystemLanguage
string langCode = LanguageDefinitions.FromSystemLanguage(Application.systemLanguage);| System Language | Code |
|---|---|
| English | en |
| Spanish | es |
| French | fr |
| German | de |
| Japanese | ja |
| Chinese (Simplified) | zh-hans |
| Arabic | ar |
Get all languages that have translation files available at runtime.
// Get language codes only
IEnumerable<string> codes = LocalizationManager.GetAvailableLanguageCodes();
foreach (string code in codes)
{
Debug.Log($"Available: {code}");
}
// Get display names (English names)
IEnumerable<string> names = LocalizationManager.GetAvailableLanguages();
foreach (string name in names)
{
Debug.Log($"Available: {name}"); // e.g., "English", "Spanish"
}
// Get display names with native names
IEnumerable<string> namesWithNative = LocalizationManager.GetAvailableLanguages(withNativeNames: true);
foreach (string name in namesWithNative)
{
Debug.Log($"Available: {name}"); // e.g., "English (English)", "Spanish (español)"
}// Check if a specific language is available
bool hasSpanish = LocalizationManager.IsLanguageAvailable("es");
bool hasJapanese = LocalizationManager.IsLanguageAvailable("ja");Display language names in their native form (e.g., "日本語" for Japanese).
// Get display name in English (default)
string englishName = LocalizationManager.GetLanguageDisplayName("ja"); // "Japanese"
string spanishName = LocalizationManager.GetLanguageDisplayName("es"); // "Spanish"
// Get native display name
string nativeJapanese = LocalizationManager.GetLanguageDisplayName("ja", native: true); // "日本語"
string nativeSpanish = LocalizationManager.GetLanguageDisplayName("es", native: true); // "español"// Convert display name back to code
string code = LocalizationManager.GetLanguageCode("Japanese"); // "ja"
string codeNative = LocalizationManager.GetLanguageCode("日本語", nativeName: true); // "ja"// Check if language is RTL (Right-to-Left)
bool isRtl = LanguageDefinitions.IsRightToLeft("ar"); // true for Arabic
bool isRtl = LanguageDefinitions.IsRightToLeft("he"); // true for Hebrew
// Get fallback language
string fallback = LanguageDefinitions.GetFallbackLanguage("en-US"); // "en"Change the current language at runtime. All bound text components will update automatically.
// Set language by code
LocalizationManager.SetLanguage("es"); // Switch to Spanish
LocalizationManager.SetLanguage("ja"); // Switch to Japanese
// Set with fallback option (default: true)
// If the requested language isn't available, it will try fallback or use default
LocalizationManager.SetLanguage("en-GB", useFallback: true);// Get current language code
string current = LocalizationManager.CurrentLanguage; // e.g., "en"
// Check if current language is RTL
bool isRtl = LocalizationManager.IsRightToLeft; // true for Arabic, Hebrew, etc.
// Get default language from config
string defaultLang = LocalizationManager.DefaultLanguage;// Basic translation
string text = LocalizationManager.GetText("greeting");
// With format parameters
string welcome = LocalizationManager.GetText("welcome", "Player");
string stats = LocalizationManager.GetText("stats", "100", "50");
// Translation file example:
// "welcome": "Welcome, {0}!"
// "stats": "Health: {0}, Mana: {1}"The system supports resolving parameters as localization keys using the Key struct.
// Localization data:
// "welcome": "Welcome to {0}"
// "game_name": "My Game Name"
// All of these output: "Welcome to My Game Name"
// 1. Pass literal string (no resolution)
LocalizationManager.GetText("welcome", "My Game Name");
// 2. Cast string to Key (resolves as localization key)
LocalizationManager.GetText("welcome", (Key)"game_name");
// 3. Use Key.From() method
LocalizationManager.GetText("welcome", Key.From("game_name"));
// 4. Implicit conversion from string
Key gameKey = "game_name";
LocalizationManager.GetText("welcome", gameKey);
// 5. All parameters resolved as keys (convenience method)
LocalizationManager.GetTextWithParamKeys("welcome", "game_name");
// 6. Mixed parameters - some literal, some keys
// "player_welcome": "Welcome {0}, you have {1} new messages"
// "player_name": "Hero"
LocalizationManager.GetText("player_welcome", (Key)"player_name", "5");
// Output: "Welcome Hero, you have 5 new messages"Cleaner syntax using string extensions:
// String extension for GetText
"welcome".Localized("My Game Name"); // literal
"welcome".Localized((Key)"game_name"); // key resolved
// Array extensions
string[] options = "graphics".LocalizedArray(); // GetArray
string quality = "graphics".LocalizedArrayElement(0); // GetArrayTextFor translations stored as arrays (e.g., dropdown options).
// Get entire array
string[] options = LocalizationManager.GetArray("difficulty_options");
// Returns: ["Easy", "Normal", "Hard", "Expert"]
// Get specific element
string difficulty = LocalizationManager.GetArrayText("difficulty_options", 2); // "Hard"
// Get with bounds checking (returns placeholder if out of range)
string invalid = LocalizationManager.GetArrayText("difficulty_options", 10); // "[difficulty_options:10]"
// Using Key struct (supports implicit conversion)
string[] graphics = LocalizationManager.GetArray((Key)"graphics_options");
string quality = LocalizationManager.GetArrayText(Key.From("graphics_options"), 0);
// Extension methods
string[] difficulties = "difficulty_options".LocalizedArray();
string easy = "difficulty_options".LocalizedArrayElement(0);// Check if key exists in current language
bool hasKey = LocalizationManager.HasKey("greeting");
// Check if key exists in default language
bool hasInDefault = LocalizationManager.HasKeyInDefault("greeting");
// Get all available keys
IEnumerable<string> allKeys = LocalizationManager.GetAllKeys();The LocalizationTextComponent automatically binds text components to the localization system.
The easiest way to bind text components is using the BindText methods on LocalizationManager:
// Simple binding
LocalizationManager.BindText(myTextComponent, "greeting");
// With format parameters
LocalizationManager.BindText(myTextComponent, "welcome_message", args: "Player");
LocalizationManager.BindText(myTextComponent, "stats", args: new object[] { 100, 50 });
// With array index (for array-type translations)
LocalizationManager.BindText(myTextComponent, "difficulty_options", arrayIndex: 2);
// With text processor
LocalizationManager.BindText(myTextComponent, "greeting", textProcessor: text => text.ToUpper());
// Full example
LocalizationManager.BindText(
myTextComponent,
"welcome_message",
arrayIndex: -1,
textProcessor: text => $"<color=green>{text}</color>",
args: "Player"
);// Bind dropdown to array translation
LocalizationManager.BindText(myDropdown, "difficulty_options");
// Limit number of options
LocalizationManager.BindText(myDropdown, "difficulty_options", arrayMaxSize: 5);
// With text processor applied to each option
LocalizationManager.BindText(
myDropdown,
"menu_items",
arrayMaxSize: 10,
textProcessor: text => text.ToUpper()
);// Same API as TMP_Text
LocalizationManager.BindText(legacyText, "greeting");
LocalizationManager.BindText(legacyText, "welcome", args: "Player");
LocalizationManager.BindText(legacyText, "stats", arrayIndex: -1, args: new object[] { 100, 50 });// Same API as TMP_Dropdown
LocalizationManager.BindText(legacyDropdown, "difficulty_options");
LocalizationManager.BindText(legacyDropdown, "menu_items", arrayMaxSize: 5);// Same API as TMP_Text
LocalizationManager.BindText(textMesh, "greeting");
LocalizationManager.BindText(textMesh, "welcome", args: "Player");
LocalizationManager.BindText(textMesh, "title", arrayIndex: 0);For more control, you can work with LocalizationTextComponent directly:
// Set translation key
component.TranslationKey = "welcome_message";
// For array values: get specific index (-1 for string value)
component.ArrayIndex = 2; // Get 3rd element from array
// For dropdowns: limit number of options
component.ArraySizeLimit = 5; // Show max 5 options
// Format parameters
component.FormatParameters = new[] { "Player", "100" };
// Or use the method:
component.SetFormatParameters("Player", "100");
// Set individual parameter
component.SetFormatParameter(0, "New Name");// Force text update
component.UpdateText();
// Force complete refresh (re-initializes components)
component.ForceRefresh();
// Add text processor (modifies text before display)
component.AddTextProcessor(text => text.ToUpper());
component.AddTextProcessor(text => $"[ {text} ]");
// Remove processor
component.RemoveTextProcessor(myProcessor);
// Clear all processors
component.ClearTextProcessors();Text processors allow you to modify the translated text before it's displayed.
// Example: Add color tags
component.AddTextProcessor(text => $"<color=green>{text}</color>");
// Example: Truncate long text
component.AddTextProcessor(text =>
text.Length > 20 ? text.Substring(0, 17) + "..." : text);
// Example: Add prefix based on language
component.AddTextProcessor(text =>
LocalizationManager.CurrentLanguage == "ja" ? $"【{text}】" : text);// Subscribe to text update event
component.onTextUpdated.AddListener(updatedText =>
{
Debug.Log($"Text updated to: {updatedText}");
});// Check component type
TextComponentType type = component.ComponentType;
// Values: TMPText, TMPDropdown, LegacyText, LegacyDropdown, TextMesh, None
// Check if attached to dropdown
bool isDropdown = component.IsDropdown;
// Get current displayed text
string currentText = component.CurrentText;Subscribe to localization events to react to language changes.
Triggered when the language is changed. All localized components update automatically.
// Subscribe
LocalizationManager.OnLanguageChanged += OnLanguageChanged;
// Handler
void OnLanguageChanged()
{
Debug.Log($"Language changed to: {LocalizationManager.CurrentLanguage}");
// Update UI, reload textures, etc.
}
// Unsubscribe
LocalizationManager.OnLanguageChanged -= OnLanguageChanged;Triggered when there's an error loading a language file.
LocalizationManager.OnLanguageLoadError += OnLanguageError;
void OnLanguageError(string errorMessage)
{
Debug.LogError($"Language load error: {errorMessage}");
}Triggered when a translation key is not found.
LocalizationManager.OnMissingTranslation += OnMissingKey;
void OnMissingKey(string key)
{
Debug.LogWarning($"Missing translation: {key}");
}#if UNITY_EDITOR
// Save locale data
LocalizationManager.SaveLocaleToFile(path, localeData, compress: true);
// Load locale data
LocaleData data = LocalizationManager.LoadLocaleFromFile(path);
// Get file path for language
string filePath = LocalizationManager.GetLanguageFilePath("en");
// Refresh available languages
LocalizationManager.RefreshAvailableLanguages();
#endif// Get languages directory path
string path = LocalizationManager.LanguagesPath;
// Check anti-tamper status
bool antiTamper = LocalizationManager.IsAntiTamperEnabled;
// Get selected languages (when protection is enabled)
IReadOnlyList<string> selected = LocalizationManager.SelectedLanguages;// Dispose resources (called automatically on application quit)
LocalizationManager.Dispose();public class LanguageSelector : MonoBehaviour
{
[SerializeField] private TMP_Dropdown dropdown;
void Start()
{
// Get available languages
var languages = LocalizationManager.GetAvailableLanguages().ToList();
var codes = LocalizationManager.GetAvailableLanguageCodes().ToList();
// Populate dropdown
dropdown.ClearOptions();
dropdown.AddOptions(languages);
// Set current selection
dropdown.value = codes.IndexOf(LocalizationManager.CurrentLanguage);
// Handle selection
dropdown.onValueChanged.AddListener(index =>
{
LocalizationManager.SetLanguage(codes[index]);
});
}
}public class ScoreDisplay : MonoBehaviour
{
[SerializeField] private LocalizationTextComponent localizedText;
void Update()
{
// Update score display with current values
localizedText.SetFormatParameters(
ScoreManager.CurrentScore.ToString(),
ScoreManager.HighScore.ToString()
);
}
}public class MainMenuBinder : MonoBehaviour
{
[SerializeField] private TMP_Text titleText;
[SerializeField] private TMP_Text playButtonText;
[SerializeField] private TMP_Text scoreText;
[SerializeField] private TMP_Dropdown difficultyDropdown;
[SerializeField] private TextMesh versionText3D;
void Start()
{
// Simple bindings
LocalizationManager.BindText(titleText, "game_title");
LocalizationManager.BindText(playButtonText, "play_button");
LocalizationManager.BindText(versionText3D, "version_info", args: "1.0.0");
// Score with format parameters
UpdateScore(0, 0);
// Dropdown with difficulty options
LocalizationManager.BindText(difficultyDropdown, "difficulty_options", arrayMaxSize: 4);
// Subscribe to score changes
ScoreManager.OnScoreChanged += UpdateScore;
}
void UpdateScore(int current, int high)
{
LocalizationManager.BindText(
scoreText,
"score_display",
args: new object[] { current, high }
);
}
}public class StyledTextBinder : MonoBehaviour
{
[SerializeField] private TMP_Text headerText;
[SerializeField] private TMP_Text warningText;
void Start()
{
// Header with color styling
LocalizationManager.BindText(
headerText,
"level_header",
textProcessor: text => $"<size=32><b>{text}</b></size>"
);
// Warning with color and icon
LocalizationManager.BindText(
warningText,
"warning_message",
textProcessor: text => $"<color=red>⚠ {text}</color>"
);
}
}public class RtlLayoutHandler : MonoBehaviour
{
[SerializeField] private RectTransform contentPanel;
void Start()
{
LocalizationManager.OnLanguageChanged += AdjustLayout;
AdjustLayout();
}
void AdjustLayout()
{
// Adjust anchor/pivot for RTL languages
if (LocalizationManager.IsRightToLeft)
{
contentPanel.anchorMin = new Vector2(1, 0);
contentPanel.anchorMax = new Vector2(1, 1);
contentPanel.pivot = new Vector2(1, 0.5f);
}
else
{
contentPanel.anchorMin = new Vector2(0, 0);
contentPanel.anchorMax = new Vector2(0, 1);
contentPanel.pivot = new Vector2(0, 0.5f);
}
}
}public class GameMessageSystem : MonoBehaviour
{
[SerializeField] private TMP_Text welcomeText;
[SerializeField] private TMP_Text equipText;
[SerializeField] private TMP_Dropdown graphicsDropdown;
void Start()
{
// Localization data:
// "welcome": "Welcome to {0}!"
// "game_name": "Epic Adventure"
// "player_equip": "{0} equipped {1}"
// "player_name": "Hero"
// "weapon_sword": "Iron Sword"
// "graphics_options": ["Low", "Medium", "High", "Ultra"]
// Welcome with resolved game name
welcomeText.text = "welcome".Localized((Key)"game_name");
// Output: "Welcome to Epic Adventure!"
// Mixed parameters - player name as key, weapon as literal
equipText.text = LocalizationManager.GetText(
"player_equip",
(Key)"player_name", // Resolved: "Hero"
"Wooden Staff" // Literal
);
// Output: "Hero equipped Wooden Staff"
// Using convenience method when all params are keys
equipText.text = LocalizationManager.GetTextWithParamKeys(
"player_equip",
"player_name", // Both resolved as keys
"weapon_sword"
);
// Output: "Hero equipped Iron Sword"
// Populate dropdown using array extension
string[] options = "graphics_options".LocalizedArray();
graphicsDropdown.ClearOptions();
graphicsDropdown.AddOptions(options.ToList());
}
void ShowDynamicMessage(string messageKey, params object[] args)
{
// Pass mixed args directly - Key objects resolved, others treated as literals
string message = LocalizationManager.GetText(messageKey, args);
Debug.Log(message);
}
void ExampleUsage()
{
// Can mix types in the array
ShowDynamicMessage(
"reward_message",
(Key)"player_name", // Resolved as key
100, // Converted to string "100"
"Gold" // Literal string
);
}
}