Skip to content

API Reference

Chamelingo provides a simple, powerful C# API for Unity game localization. This documentation covers all public APIs available for developers.

Quick Start

// Get current language
CultureInfo currentLang = Chamelingo.CurrentLanguage;

// Translate text
string welcomeText = Chamelingo.Translate("menu.welcome");

// Change language
Chamelingo.LoadLanguage(new CultureInfo("de"));

// Subscribe to language changes
Chamelingo.Subscribe(OnLanguageChanged);

Core API: Chamelingo Class

The main static class providing access to all localization functionality.

API Overview

// Get current language
CultureInfo lang = Chamelingo.CurrentLanguage;

// Switch to a different language
Chamelingo.LoadLanguage(new CultureInfo("de"));

// Get all available languages
IEnumerable<CultureInfo> languages = Chamelingo.GetAvailableLanguages();

// Translate text
string text = Chamelingo.Translate("menu.welcome");
string upperText = Chamelingo.Translate("menu.start", TextCasing.AllUppercase);

// Subscribe to language changes
Chamelingo.Subscribe(OnLanguageChanged);
Chamelingo.Unsubscribe(OnLanguageChanged);

Detailed Reference:


Properties

CurrentLanguage

public static CultureInfo CurrentLanguage { get; }

Gets the currently active language.

Returns: The active CultureInfo representing the current language.

Example:

CultureInfo lang = Chamelingo.CurrentLanguage;
Debug.Log($"Current language: {lang.EnglishName}"); // "English", "German", etc.


Methods

LoadLanguage

public static void LoadLanguage(CultureInfo cultureInfo)

Switches to a new language and persists the choice. Triggers language change notifications to all subscribers.

Neutral Cultures Only

Chamelingo uses neutral cultures (language without region) based on IETF language tags. Use "de" for German, not "de-DE" or "de-AT". Always check available languages first to ensure the language exists in your project.

Parameters: - cultureInfo - The neutral culture to load using IETF language tag (e.g., CultureInfo.GetCultureInfoByIetfLanguageTag("de") for German, "fr" for French)

Best Practice:

// ✅ RECOMMENDED: Check if language exists before loading
var availableLanguages = Chamelingo.GetAvailableLanguages();
var desiredLanguageTag = "de"; // German
var germanCulture = CultureInfo.GetCultureInfoByIetfLanguageTag(desiredLanguageTag);

if (availableLanguages.Any(lang => lang.IetfLanguageTag == desiredLanguageTag))
{
    Chamelingo.LoadLanguage(germanCulture);
}
else
{
    Debug.LogWarning($"Language '{desiredLanguageTag}' not available");
}

// ⚠️ Without checking (not recommended)
Chamelingo.LoadLanguage(CultureInfo.GetCultureInfoByIetfLanguageTag("de")); // May fail if German isn't in your project

Neutral vs Region-Specific IETF Tags:

// ✅ CORRECT: Neutral culture (primary language subtag only)
Chamelingo.LoadLanguage(CultureInfo.GetCultureInfoByIetfLanguageTag("de"));  // German
Chamelingo.LoadLanguage(CultureInfo.GetCultureInfoByIetfLanguageTag("fr"));  // French
Chamelingo.LoadLanguage(CultureInfo.GetCultureInfoByIetfLanguageTag("ja"));  // Japanese
Chamelingo.LoadLanguage(CultureInfo.GetCultureInfoByIetfLanguageTag("zh"));  // Chinese

// ❌ INCORRECT: Region-specific culture (language-region subtags - will not work)
Chamelingo.LoadLanguage(CultureInfo.GetCultureInfoByIetfLanguageTag("de-DE"));  // German (Germany) - DON'T USE
Chamelingo.LoadLanguage(CultureInfo.GetCultureInfoByIetfLanguageTag("en-US"));  // English (US) - DON'T USE
Chamelingo.LoadLanguage(CultureInfo.GetCultureInfoByIetfLanguageTag("fr-CA"));  // French (Canada) - DON'T USE
Chamelingo.LoadLanguage(CultureInfo.GetCultureInfoByIetfLanguageTag("zh-CN"));  // Chinese (China) - DON'T USE


GetAvailableLanguages

public static IEnumerable<CultureInfo> GetAvailableLanguages()

Gets all languages available in your project.

Returns: Collection of supported CultureInfo objects, or empty collection if none are available.

Example:

// Get all available languages
var languages = Chamelingo.GetAvailableLanguages();

// Populate a dropdown
foreach (var language in languages)
{
    dropdown.options.Add(new Dropdown.OptionData(language.EnglishName));
}

// Check if specific language is available
bool hasGerman = languages.Any(l => l.IetfLanguageTag == "de");


Translate (Simple)

public static string Translate(string key)

Translates a key to the current language.

Parameters: - key - The translation key (e.g., "menu.start", "ui.score")

Returns: The translated text, or the key itself if translation not found.

Example:

string welcomeText = Chamelingo.Translate("menu.welcome");
string scoreLabel = Chamelingo.Translate("ui.score");
myTextComponent.text = Chamelingo.Translate("player.name");


Translate (With Casing)

public static string Translate(string key, TextCasing casing, CultureInfo culture = null)

Translates a key with optional text casing transformation.

Parameters: - key - The translation key - casing - Text casing to apply (see TextCasing enum) - culture - Optional culture for culture-specific casing (defaults to current language)

Returns: The translated and formatted text, or the key itself if not found.

Example:

// All uppercase
string upperTitle = Chamelingo.Translate("menu.start", TextCasing.AllUppercase);
// Result: "START GAME"

// Title case
string titleCase = Chamelingo.Translate("player.name", TextCasing.TitleCase);
// Result: "Player Name"

// First letter uppercase
string sentence = Chamelingo.Translate("message.welcome", TextCasing.FirstLetterUppercase);
// Result: "Welcome to the game"


Subscribe

public static void Subscribe(Action<CultureInfo> callback)

Subscribes to language change notifications. The callback is invoked immediately with the current language.

Parameters: - callback - Action to invoke when language changes, receives the new CultureInfo

Example:

void Start()
{
    // Subscribe to language changes
    Chamelingo.Subscribe(OnLanguageChanged);
}

void OnLanguageChanged(CultureInfo newLanguage)
{
    Debug.Log($"Language changed to: {newLanguage.EnglishName}");
    RefreshUI();
}

void OnDestroy()
{
    // Always unsubscribe to prevent memory leaks
    Chamelingo.Unsubscribe(OnLanguageChanged);
}


Unsubscribe

public static void Unsubscribe(Action<CultureInfo> callback)

Unsubscribes from language change notifications.

Parameters: - callback - The callback to remove (must be the same instance used in Subscribe)

Example:

void OnDestroy()
{
    Chamelingo.Unsubscribe(OnLanguageChanged);
}


TextCasing Enum

Defines text transformation options for translated text.

public enum TextCasing
{
    None = 0,
    FirstLetterUppercase = 1,
    FirstLetterLowercase = 2,
    AllUppercase = 3,
    AllLowercase = 4,
    TitleCase = 5
}

Values

Value Description Example Input Example Output
None No changes applied "hello world" "hello world"
FirstLetterUppercase First letter uppercase "hello world" "Hello world"
FirstLetterLowercase First letter lowercase "Hello World" "hello World"
AllUppercase All letters uppercase "Hello World" "HELLO WORLD"
AllLowercase All letters lowercase "Hello World" "hello world"
TitleCase First letter of each word uppercase "hello brave world" "Hello Brave World"

Usage:

// Menu items often use uppercase
string menuItem = Chamelingo.Translate("menu.start", TextCasing.AllUppercase);

// Titles use title case
string levelName = Chamelingo.Translate("level.name", TextCasing.TitleCase);

// Sentences use first letter uppercase
string description = Chamelingo.Translate("item.desc", TextCasing.FirstLetterUppercase);


UI Components

Chamelingo provides ready-to-use components that automatically translate and update UI text elements.

ChamelingoTMP

TextMeshPro localization component. Attach to any GameObject with a TMP_Text component.

Requirements: Requires TMP_Text component on the same GameObject.

Features: - ✅ Automatic translation on language change - ✅ Composite text support (dynamic parameters) - ✅ Optional auto-refresh for real-time updates - ✅ Text casing support - ✅ Editor integration with live preview

Basic Usage:

// Attach ChamelingoTMP component to a TextMeshPro object in Inspector
// Set Translation Key to "menu.welcome"
// Text will automatically translate when language changes

Advanced Usage (Code):

var tmpText = GetComponent<ChamelingoTMP>();

// Change translation key at runtime
tmpText.SetTranslationKey("menu.settings", TextCasing.TitleCase);

// Use composite text with parameters
tmpText.SetParameter("playerName", "Alice");
tmpText.SetParameter("score", "1250");

// Enable auto-refresh for dynamic content
tmpText.SetAutoRefresh(true, interval: 0.5f);


ChamelingoUnityText

Legacy Unity UI Text localization component. Attach to any GameObject with a Text component.

Requirements: Requires Unity UI Text component on the same GameObject.

Features: - ✅ Same features as ChamelingoTMP - ✅ Compatible with legacy Unity UI system - ✅ Drop-in replacement for standard Text component

Usage:

var unityText = GetComponent<ChamelingoUnityText>();
unityText.SetTranslationKey("ui.health");


ChamelingoTextBase (Component API)

Both ChamelingoTMP and ChamelingoUnityText inherit from ChamelingoTextBase, providing the following API:

Methods

SetTranslationKey

public void SetTranslationKey(string key, TextCasing casing = TextCasing.None)

Sets a new translation key and immediately updates the text.

Example:

textComponent.SetTranslationKey("menu.start");
textComponent.SetTranslationKey("menu.title", TextCasing.AllUppercase);


GetTranslationKey

public string GetTranslationKey()

Gets the current translation key.


SetTranslationKeyCasing

public void SetTranslationKeyCasing(TextCasing casing)

Changes the text casing without changing the translation key.


SetParameter

public void SetParameter(string key, string value)

Sets a single parameter for composite text (dynamic text with placeholders).

Example:

// Template: "Welcome, {playerName}!"
textComponent.SetParameter("playerName", "Alice");
// Result: "Welcome, Alice!"


SetParameters

public void SetParameters(Dictionary<string, string> parameters)

Sets multiple parameters at once for composite text.

Example:

var params = new Dictionary<string, string>
{
    { "playerName", "Bob" },
    { "score", "9999" },
    { "level", "10" }
};
textComponent.SetParameters(params);


ClearParameters

public void ClearParameters()

Clears all runtime parameters for composite text.


RefreshCompositeText

public void RefreshCompositeText()

Manually refreshes composite text. Useful when parameter values change but you haven't called SetParameter.


SetAutoRefresh

public void SetAutoRefresh(bool enabled, float interval = 0.1f)

Enables or disables automatic refresh for composite text.

Parameters: - enabled - Whether to enable auto-refresh - interval - Update interval in seconds (default: 0.1)

Example:

// Update timer text every 0.1 seconds
timerText.SetAutoRefresh(true, 0.1f);


IsUsingCompositeText

public bool IsUsingCompositeText()

Returns whether the component is using composite text mode.

GetCompositeTemplate

public string GetCompositeTemplate()

Gets the current composite text template.


Custom Localizer

The ChamelingoCustomLocalizer component enables localization of any component property beyond text.

Overview

While UI Components handle text localization, the Custom Localizer works with: - Unity Objects (Sprite, Material, AudioClip, etc.) - Primitive types (int, float, string, bool, etc.) - Unity value types (Vector2/3/4, Color, Quaternion) - Enums

Basic Usage

The Custom Localizer is primarily configured through the Unity Inspector.

Inspector Configuration:

1. Add ChamelingoCustomLocalizer component to a GameObject
2. Select target component from dropdown
3. Select property/field to localize
4. Configure default value
5. Add language-specific mappings


Supported Types

Unity Objects

All types derived from UnityEngine.Object: - Sprite, Texture, Material, AudioClip, AnimationClip - GameObject, ScriptableObject - Any custom Unity Object type

Primitive Types

  • Numeric: int, float, double, long, short, byte, decimal
  • Text: string
  • Boolean: bool
  • Enums: Any enum type (case-insensitive parsing)

Unity Value Types

  • Vector2
  • Vector3
  • Vector4
  • Color
  • Quaternion

Programmatic API

While the Custom Localizer is primarily designed for Inspector use, the full API is available for runtime configuration.

Properties

TargetComponent

public Component TargetComponent { get; set; }
Gets or sets the target component to modify. Must be on the same GameObject.

PropertyName

public string PropertyName { get; set; }
Gets or sets the name of the property or field to modify.

PropertyValueType

public ValueType PropertyValueType { get; set; }
Gets or sets the type of value: ValueType.UnityObject or ValueType.Primitive.

DefaultObjectValue

public UnityEngine.Object DefaultObjectValue { get; set; }
Default value for Unity Object types when no language mapping is found.

DefaultPrimitiveValue

public string DefaultPrimitiveValue { get; set; }
Default value for primitive types when no language mapping is found.

ValueMappings

public List<LanguageValueMapping> ValueMappings { get; }
Gets the list of language-specific value mappings.


Methods

AddObjectMapping

public void AddObjectMapping(string languageCode, UnityEngine.Object value)
Adds a language mapping for Unity Objects.

AddPrimitiveMapping

public void AddPrimitiveMapping(string languageCode, string value)
Adds a language mapping for primitives.

ClearMappings

public void ClearMappings()
Clears all language value mappings.

Refresh

public void Refresh()
Manually refreshes the localization by applying the current language.

GetPropertyType

public Type GetPropertyType()
Gets the type of the property/field being localized. Returns null if not found.

IsPrimitiveType

public bool IsPrimitiveType()
Determines if the property type is a supported primitive type.


Usage Example

// Runtime configuration
var localizer = gameObject.AddComponent<ChamelingoCustomLocalizer>();
localizer.TargetComponent = GetComponent<Image>();
localizer.PropertyName = "sprite";
localizer.PropertyValueType = ValueType.UnityObject;
localizer.DefaultObjectValue = defaultSprite;

// Add mappings
localizer.AddObjectMapping("en", englishSprite);
localizer.AddObjectMapping("de", germanSprite);
localizer.AddObjectMapping("fr", frenchSprite);

// Apply
localizer.Refresh();

Error Handling

Missing Component:

// If target component is removed or doesn't exist
// Unity Console: "Target component not found on GameObject"
// Component status: Error state in Dashboard

Invalid Property:

// If property name doesn't exist or is inaccessible
// Unity Console: "Property 'invalidProp' not found or inaccessible"
// Component status: Error state

Parse Errors:

// If primitive value format is invalid
// Unity Console: "Failed to parse value for property: Invalid format"
// Behavior: Falls back to default value

Best Practices

Always Set Default Values Ensure components work even if language mappings are incomplete:

// Set a sensible default that works for all languages
Default Value: yourDefaultSprite

Test All Languages Verify mappings work by switching languages in play mode:

Chamelingo.LoadLanguage(CultureInfo.GetCultureInfoByIetfLanguageTag("de"));


Troubleshooting

Problem: Property not updating - Check that target component exists on GameObject - Verify property name is correct (case-sensitive) - Ensure property has public setter or is public field - Check Unity Console for specific error messages

Problem: Parse errors for primitives - Verify format matches expected pattern - Use period (.) for decimals, not comma (,) - Check for extra spaces (only after commas in vectors/colors) - Ensure enum values match definition (case-insensitive)

Problem: Missing references after scene reload - Check that Chamelingo package is properly imported - Verify script GUID matches in .meta files - Re-import package if necessary


Best Practices

Memory Management

Always unsubscribe from language change events to prevent memory leaks:

void OnEnable()
{
    Chamelingo.Subscribe(OnLanguageChanged);
}

void OnDisable()
{
    Chamelingo.Unsubscribe(OnLanguageChanged);
}

Performance

  • Use components (ChamelingoTMP, ChamelingoUnityText) for UI elements that need automatic updates
  • Use the static Chamelingo.Translate() API for one-time translations or non-UI text
  • Enable auto-refresh only when needed for dynamic content

Translation Keys

Use a consistent naming convention for translation keys:

// Good: Hierarchical and descriptive
"menu.start"
"menu.settings"
"ui.health"
"ui.score"
"dialog.welcome.title"
"dialog.welcome.message"

// Avoid: Generic or unclear
"text1"
"button"
"msg"

Common Patterns

Language Selector

Chamelingo includes a pre-built language dropdown component that you can add directly from the Unity Editor.

Adding the Component:

Unity Editor → GameObject → UI → Chamelingo → Language Selection

This creates a fully configured dropdown with automatic language detection and switching.

Programmatic Usage:

// Get reference to the component
var languageDropdown = GetComponent<ChamelingoLanguageDropdown>();

// Set language programmatically
languageDropdown.SetLanguageByCode("de"); // Switch to German

// Listen to language changes
languageDropdown.OnLanguageChanged.AddListener(OnLanguageChanged);

void OnLanguageChanged(CultureInfo newLanguage)
{
    Debug.Log($"User selected: {newLanguage.EnglishName}");
}

// Access currently selected language
CultureInfo selected = languageDropdown.SelectedLanguage;

// Refresh dropdown if languages change
languageDropdown.Refresh();

Display Options:

The dropdown supports multiple display modes (configurable in Inspector):

  • Code: "en", "de", "fr"
  • Native Name: "English", "Deutsch", "Français"
  • English Name: "English", "German", "French"
  • Code + Native: "en (English)", "de (Deutsch)", "fr (Français)"
  • Code + English: "en - English", "de - German", "fr - French"
  • Native + English: "English (English)", "Deutsch (German)", "Français (French)"

Custom Implementation (Advanced):

If you need custom behavior, you can create your own language selector:

public class CustomLanguageSelector : MonoBehaviour
{
    public TMP_Dropdown dropdown;

    void Start()
    {
        PopulateLanguages();
        dropdown.onValueChanged.AddListener(OnLanguageSelected);
    }

    void PopulateLanguages()
    {
        dropdown.ClearOptions();
        var languages = Chamelingo.GetAvailableLanguages().ToList();
        var options = languages.Select(l => l.EnglishName).ToList();
        dropdown.AddOptions(options);

        // Set current language as selected
        var currentIndex = languages.FindIndex(l => 
            l.IetfLanguageTag == Chamelingo.CurrentLanguage.IetfLanguageTag);
        if (currentIndex >= 0)
            dropdown.value = currentIndex;
    }

    void OnLanguageSelected(int index)
    {
        var languages = Chamelingo.GetAvailableLanguages().ToList();
        if (index < languages.Count)
            Chamelingo.LoadLanguage(languages[index]);
    }
}

Dynamic Score Display

public class ScoreDisplay : MonoBehaviour
{
    private ChamelingoTMP scoreText;
    private int currentScore;

    void Start()
    {
        scoreText = GetComponent<ChamelingoTMP>();
        // Template in translation file: "Score: {score}"
        UpdateScore(0);
    }

    public void UpdateScore(int newScore)
    {
        currentScore = newScore;
        scoreText.SetParameter("score", currentScore.ToString());
    }
}

Player Name Display

public class WelcomeMessage : MonoBehaviour
{
    private ChamelingoTMP welcomeText;

    void Start()
    {
        welcomeText = GetComponent<ChamelingoTMP>();
        // Template: "Welcome back, {playerName}!"
        welcomeText.SetParameter("playerName", PlayerPrefs.GetString("PlayerName", "Guest"));
    }
}

Support

For questions, feature requests, or discussions about Chamelingo, visit our GitHub Discussions.

For bug reports, please use the Issue Tracker.