Skip to content

Auto-Translation

Lexis Pro includes integrated auto-translation support using industry-leading translation services. Translate your strings directly within the Unity Editor without leaving your workflow.

ServiceAPIBest For
DeepLDeepL APIHigh-quality European language translation
ChatGPTOpenAI APIContext-aware translations, creative content
Google TranslateCloud Translation APIWide language coverage, fast processing
GeminiGoogle Gemini APICost-effective AI translations
ClaudeAnthropic APINuanced, context-aware translations

DeepL Setup

  1. Go to DeepL API
  2. Sign up for a DeepL API account (Free or Pro)
  3. Navigate to your account settings → API Keys
  4. Copy your API key
  5. Free vs Pro: DeepL auto-detects based on your key
    • Free keys end with :fx
    • Free tier: 500,000 characters/month
    • Pro tier: Pay-as-you-go pricing

Supported Languages: EN, DE, FR, ES, IT, NL, PL, PT, RU, JA, ZH, and more.

ChatGPT Setup

  1. Go to OpenAI Platform
  2. Create an account or sign in
  3. Navigate to API Keys section
  4. Click Create new secret key
  5. Copy the key (starts with sk-)
  6. Model Selection:
    • gpt-4o-mini (default): Fast, cost-effective
    • gpt-4o: Higher quality, more expensive

Note: OpenAI charges per token. Translation costs depend on text length and model.

Google Cloud Translation Setup

  1. Go to Google Cloud Console
  2. Create a new project or select existing
  3. Enable the Cloud Translation API:
    • Go to APIs & Services → Library
    • Search for "Cloud Translation API"
    • Click Enable
  4. Create an API key:
    • Go to APIs & Services → Credentials
    • Click Create Credentials → API Key
    • (Recommended) Restrict the key to Cloud Translation API only
  5. Copy the API key

Pricing: Google charges per character translated. See Cloud Translation pricing.

Gemini Setup

  1. Go to Google AI Studio
  2. Sign in with your Google account
  3. Click Get API KeyCreate API key
  4. Copy the API key

Pricing: Gemini 2.0 Flash is very cost-effective. See Gemini API pricing.

Claude Setup

  1. Go to Anthropic Console
  2. Create an account or sign in
  3. Navigate to API Keys
  4. Click Create Key
  5. Copy the key (starts with sk-ant-)

Pricing: Claude charges per token. See Anthropic pricing.

Lexis supports secure credential storage through environment variables (recommended) or EditorPrefs.

Set environment variables before launching Unity:

ServiceEnvironment Variable
DeepLLEXIS_DEEPL_API_KEY
ChatGPTLEXIS_OPENAI_API_KEY
GoogleLEXIS_GOOGLE_TRANSLATE_API_KEY
GeminiLEXIS_GEMINI_API_KEY
ClaudeLEXIS_CLAUDE_API_KEY

macOS/Linux:

bash
export LEXIS_DEEPL_API_KEY="your-deepl-api-key"
export LEXIS_OPENAI_API_KEY="sk-your-openai-api-key"
export LEXIS_GOOGLE_TRANSLATE_API_KEY="your-google-api-key"
export LEXIS_GEMINI_API_KEY="your-gemini-api-key"
export LEXIS_CLAUDE_API_KEY="sk-ant-your-claude-api-key"

Windows (PowerShell):

powershell
$env:LEXIS_DEEPL_API_KEY = "your-deepl-api-key"
$env:LEXIS_OPENAI_API_KEY = "sk-your-openai-api-key"
$env:LEXIS_GOOGLE_TRANSLATE_API_KEY = "your-google-api-key"
$env:LEXIS_GEMINI_API_KEY = "your-gemini-api-key"
$env:LEXIS_CLAUDE_API_KEY = "sk-ant-your-claude-api-key"

EditorPrefs Storage

For convenience during development, you can store credentials in EditorPrefs via Auto-Translate:

  1. Open Tools → KitStack → Lexis → Auto-Translate...
  2. Go to the Settings tab
  3. Enter your API keys in the credential fields
  4. Click Validate All Credentials to verify each service shows "Verified" (green)
  5. Keys are stored in EditorPrefs (per-machine, not in version control)

Security Warning EditorPrefs storage is convenient but less secure than environment variables. Never commit API keys to version control.

CI/CD Configuration

For automated pipelines and CI/CD environments, configure credentials via environment variables before running Unity.

GitHub Actions:

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      LEXIS_DEEPL_API_KEY: ${{ secrets.DEEPL_API_KEY }}
      LEXIS_OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
      LEXIS_GOOGLE_TRANSLATE_API_KEY: ${{ secrets.GOOGLE_TRANSLATE_API_KEY }}
      LEXIS_GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
      LEXIS_CLAUDE_API_KEY: ${{ secrets.CLAUDE_API_KEY }}
    steps:
      - uses: actions/checkout@v4
      - name: Build Unity Project
        uses: game-ci/unity-builder@v4
        with:
          projectPath: .
          targetPlatform: StandaloneWindows64

Credential Lookup Order:

  1. Environment variables (checked first)
  2. EditorPrefs (fallback for local development)

Menu: Tools → KitStack → Lexis → Auto-Translate...

The Auto-Translate window provides a unified interface for managing auto-translation.

Tabs

TabPurpose
TranslateTranslate individual strings with preview
SettingsTranslation context, service credentials, and credential validation
MemoryView and manage translation cache with per-language-pair breakdown

Translate Tab

  1. Service Selection: Choose DeepL, ChatGPT, Google Translate, Gemini, or Claude
  2. Service Status: Shows verification status next to the service dropdown — "Verified" (green), "Not Verified" (yellow), "Verification Failed" (red), or "Not Configured" (red)
  3. Language Selection: Source and target language codes
  4. Text Input: Enter text to translate
  5. Preview: See translation result before applying

Settings Tab

  1. Translation Context: Assign or create a TranslationContext ScriptableObject that provides project-specific instructions to AI translators (tone, terminology, placeholders). Click Create to generate one automatically if none exists.

  2. Service Credentials:

    • DeepL: API key (Free or Pro), auto-detects endpoint
    • ChatGPT: OpenAI API key
    • Google: Cloud Translation API key
    • Gemini: Google AI API key
    • Claude: Anthropic API key
  3. Validate All Credentials: Validates each configured service against its API. Status persists across sessions:

    • Verified (green): API key confirmed working
    • Verification Failed (red): API call failed
    • Not Verified (yellow): Configured but not yet validated
    • Not Configured (red): No API key set

Memory Tab

  1. Statistics: Total cached translations, total source characters, services used
  2. Language Pair Breakdown: Per-pair table (e.g., "en → de: 42 entries, 3,200 chars") with individual Clear buttons
  3. Clear All: Remove all cached entries

String Table Browser Integration

The String Table Browser includes two auto-translation features (Pro only):

Translate All Button:

  • Located in the toolbar next to + Add Entry (only visible for String Tables)
  • Translates all untranslated entries across all target languages in one click
  • Shows a confirmation dialog with entry count, character count, and selected service
  • Uses the Translation Context configured in the Settings tab
  • Checks Translation Memory cache first to avoid redundant API calls
  • Disabled (grayed out) when no translation service is configured

Per-Entry Translate Button (T):

  • Appears next to the Edit button on each entry row
  • Only visible when a specific target language column is selected (not "All Languages" or the default locale)
  • Translates that single entry's default value into the selected language
  • Result is written directly into the entry
  • Uses Translation Memory cache and Translation Context

TranslationContext is a ScriptableObject that provides contextual information to improve translation quality. It's especially powerful with AI-based services like ChatGPT, Claude, and Gemini, which use the context to generate more accurate, consistent, and tonally appropriate translations.

Create: Via the Settings tab Create button, or right-click → Create → KitStack → Lexis → Translation Context

Why Use TranslationContext?

Without context, translation services treat each string in isolation. This leads to:

  • Inconsistent terminology (translating "level" as "stage" sometimes and "tier" other times)
  • Wrong tone (formal language in a casual mobile game)
  • Incorrect domain assumptions (translating "tank" as a military vehicle instead of a game role)

With a well-configured TranslationContext, AI services understand your project and produce translations that:

  • Match your game's tone and style
  • Use consistent terminology throughout
  • Respect domain-specific meanings
  • Preserve brand names and untranslatable terms

Provider Support

FeatureChatGPTClaudeGeminiDeepLGoogle Translate
Project Description✓ Full support✓ Full support✓ Full support
Genre/Audience✓ Full support✓ Full support✓ Full support
Formality✓ Full support✓ Full support✓ Full support✓ Partial*
DoNotTranslate✓ Full support✓ Full support✓ Full support
Glossary✓ Full support✓ Full support✓ Full support✓ Via API**

*DeepL supports formality natively for some languages (DE, FR, IT, ES, NL, PL, PT, RU, JA). **DeepL glossaries require separate API setup; Lexis passes glossary terms via context for AI services.

Recommendation: For best translation quality, use ChatGPT or Claude with a well-configured TranslationContext. For cost-effective AI translations, use Gemini. For traditional translation without context needs, use DeepL or Google Translate.

Settings

PropertyDescription
ProjectDescriptionBrief description of your project (see below for tips)
GenreContent genre (Game, App, Website, Documentation)
TargetAudienceTarget audience (Children, Teens, Adults, All Ages)
FormalityFormality level (Default, Informal, Formal)
DoNotTranslateList of terms to preserve untranslated (brand names, etc.)
GlossaryTerm-to-translation mappings for consistent terminology

Writing a Good Project Description

The ProjectDescription field is the most important setting for AI translation quality. Write 2-4 sentences that describe:

  1. What your project is - Game, app, website, etc.
  2. Genre and setting - Fantasy RPG, sci-fi shooter, casual puzzle, business app
  3. Tone and style - Serious, humorous, formal, casual, epic, lighthearted
  4. Target audience - Age group, player type

Good Examples:

"A dark fantasy action RPG set in a medieval world overrun by demons.
The tone is serious and dramatic, with occasional dark humor.
Target audience is mature gamers (18+)."
"A cheerful puzzle game for children ages 6-12 featuring colorful animals.
The tone is friendly, encouraging, and educational.
All text should be simple and easy to understand."
"A competitive multiplayer FPS with a near-future military setting.
Communication is tactical and professional.
Target audience is teens and young adults who enjoy esports."

Poor Examples:

"My game"  // Too vague, provides no useful context
"A game where you do stuff"  // No genre, tone, or audience information

Glossary Entries

Define consistent translations for domain-specific terms. The Glossary is edited directly in the Unity Inspector:

How to Access:

  1. Create a TranslationContext asset: Right-click → Create → KitStack → Lexis → Translation Context
  2. Select the TranslationContext asset in the Project window
  3. In the Inspector, expand the Glossary section
  4. Click + to add entries, configure each with:
    • Source Term: The English term to match
    • Target Term: The desired translation
    • Target Language: Language code (e.g., "de") or leave empty for all languages

Example Configuration (Inspector):

Source TermTarget TermTarget Language
Health PointsLebenspunktede
Health PointsPoints de viefr
ManaMana(empty - keep for all)
The Dark LordDer Dunkle Fürstde

You can also configure the Glossary via code:

csharp
var context = ScriptableObject.CreateInstance<TranslationContext>();
// Access glossary (read-only property, configure via Inspector or serialization)
foreach (var entry in context.Glossary)
{
    Debug.Log($"{entry.SourceTerm} → {entry.TargetTerm} ({entry.TargetLanguage})");
}

When to use Glossary:

  • Character names that should be translated (not just transliterated)
  • Game-specific terms with established translations
  • Technical terms with specific meanings in your domain
  • Terms that might be ambiguous without context

When to use DoNotTranslate:

  • Brand names (your game title, company name)
  • Character names that should stay in English
  • Technical identifiers shown to users
  • Proper nouns that shouldn't change

Before translation, Lexis can analyze source text for common issues that may affect translation quality.

Detected Issues

Issue TypeSeverityExample
Unbalanced placeholdersErrorHello {name (missing })
Empty placeholdersErrorHello {}!
Encoding issuesErrorReplacement character \uFFFD
Multiple spacesWarningHello world
Leading/trailing whitespaceWarning Hello
Hardcoded large numbersWarningYou scored 10000 points
URLs in textInfoVisit https://example.com

Quality Levels

LevelMeaning
GoodNo issues detected
FairWarnings only
PoorContains errors

Usage

csharp
using Lexis.Editor.Translation;

var checker = new SourceQualityChecker(() => openAiApiKey);
var result = checker.CheckBasicQuality("Hello {name}!");

if (result.HasIssues)
{
    foreach (var issue in result.Issues)
    {
        Debug.LogWarning($"{issue.Type}: {issue.Description}");
    }
}

Translation Memory caches translations to reduce API calls and costs. Identical source strings return cached results instantly.

Features

  • Automatic caching: All successful translations are cached
  • Language-pair aware: Caches are specific to source/target language pairs
  • Persistent: Cache survives Unity restarts (stored in Library folder)
  • LRU eviction: Oldest entries removed when cache is full (10,000 max entries)
  • Per-pair management: View and clear cache by individual language pair

Statistics

csharp
using Lexis.Editor.Translation;

var tm = TranslationMemoryManager.Instance;
var stats = tm.GetStats();

Debug.Log($"Entries: {stats.TotalEntries}");
Debug.Log($"Characters: {stats.TotalCharacters}");
Debug.Log($"Language pairs: {stats.LanguagePairs}");
Debug.Log($"Services: {string.Join(", ", stats.Services)}");

// Per language pair breakdown
foreach (var kvp in stats.LanguagePairBreakdown)
{
    Debug.Log($"{kvp.Key}: {kvp.Value.EntryCount} entries, {kvp.Value.TotalCharacters} chars");
}

Cache Management

csharp
// Check for cached translation
if (tm.TryGetCachedTranslation("Hello", "en", "de", out string cached))
{
    Debug.Log($"Cached: {cached}");
}

// Store a translation
tm.StoreTranslation("Hello", "Hallo", "en", "de", "deepl");

// Clear specific language pair
int removed = tm.ClearForLanguagePair("en", "de");

// Clear all
tm.ClearAll();

Single Translation

csharp
using Lexis.Editor.Translation;
using Lexis.Translation;

// Using the default configured service
var result = await TranslationIntegration.TranslateAsync(
    "Hello, world!",
    "en",
    "de");

if (result.Success)
{
    Debug.Log($"Translated: {result.TranslatedText}");
    Debug.Log($"Characters: {result.CharacterCount}");
}
else
{
    Debug.LogError($"Failed: {result.GetUserFriendlyMessage()}");
}

Batch Translation

csharp
using Lexis.Editor.Translation;
using Lexis.Translation;

string[] texts = { "Hello", "World", "Welcome" };

var results = await TranslationIntegration.TranslateBatchAsync(
    texts,
    "en",
    "de",
    context: myTranslationContext,
    progress: new Progress<TranslationProgress>(p =>
    {
        Debug.Log($"Progress: {p.Completed}/{p.Total}");
    }));

for (int i = 0; i < results.Length; i++)
{
    if (results[i].Success)
    {
        Debug.Log($"{texts[i]} → {results[i].TranslatedText}");
    }
}

Using Specific Services

csharp
using Lexis.Translation.Services;

// DeepL
var deepl = new DeepLService(() => Environment.GetEnvironmentVariable("LEXIS_DEEPL_API_KEY"));
var result = await deepl.TranslateAsync("Hello", "en", "de");

// ChatGPT with custom model
var chatgpt = new OpenAIService(() => Environment.GetEnvironmentVariable("LEXIS_OPENAI_API_KEY"));
chatgpt.Model = "gpt-4o";  // or "gpt-4o-mini" (default)
var result = await chatgpt.TranslateAsync("Hello", "en", "de", myContext);

// Google Translate
var google = new GoogleTranslateService(() => Environment.GetEnvironmentVariable("LEXIS_GOOGLE_TRANSLATE_API_KEY"));
var result = await google.TranslateAsync("Hello", "en", "de");

// Gemini
var gemini = new GeminiService(() => Environment.GetEnvironmentVariable("LEXIS_GEMINI_API_KEY"));
var result = await gemini.TranslateAsync("Hello", "en", "de", myContext);

// Claude
var claude = new ClaudeService(() => Environment.GetEnvironmentVariable("LEXIS_CLAUDE_API_KEY"));
var result = await claude.TranslateAsync("Hello", "en", "de", myContext);
FeatureDeepLChatGPTGoogle TranslateGeminiClaude
Languages30+All major100+All majorAll major
Context-awareLimitedExcellentLimitedGoodExcellent
Formality controlYesVia promptNoVia promptVia prompt
Batch limit50 texts1 at a time128 texts1 at a time1 at a time
CostPer characterPer tokenPer characterPer tokenPer token
Best forEuropean languagesCreative contentWide coverageCost-effective AINuanced content
  1. Use TranslationContext for AI services to improve quality
  2. Review translations before committing - machine translation isn't perfect
  3. Use glossaries for consistent terminology (character names, game terms)
  4. Check source quality before translating to avoid propagating errors
  5. Leverage caching - the Translation Memory reduces API costs significantly
  6. Use Translate All in the String Table Browser for bulk translation of untranslated entries
  7. Set DoNotTranslate for brand names, product names, and untranslatable terms
ErrorCauseSolution
"Invalid API key"Key is incorrect or expiredVerify key in service dashboard
"Rate limited"Too many requestsWait and retry, or upgrade API plan
"Quota exceeded"Monthly limit reachedCheck usage in service dashboard
"Unsupported language"Service doesn't support languageTry a different service
"Network error"Connection failedCheck internet connection

Professional Unity Development Tools