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
OpenAI GPTOpenAI APIContext-aware translations, creative content
Google TranslateCloud Translation APIWide language coverage, fast processing

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.

OpenAI 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.

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

Set environment variables before launching Unity:

ServiceEnvironment Variable
DeepLDEEPL_API_KEY
OpenAIOPENAI_API_KEY
GoogleGOOGLE_TRANSLATE_API_KEY

macOS/Linux:

bash
export DEEPL_API_KEY="your-deepl-api-key"
export OPENAI_API_KEY="sk-your-openai-api-key"
export GOOGLE_TRANSLATE_API_KEY="your-google-api-key"

Windows (PowerShell):

powershell
$env:DEEPL_API_KEY = "your-deepl-api-key"
$env:OPENAI_API_KEY = "sk-your-openai-api-key"
$env:GOOGLE_TRANSLATE_API_KEY = "your-google-api-key"

EditorPrefs Storage

For convenience during development, you can store credentials in EditorPrefs via the Translation Window:

  1. Open Tools → KitStack → Lexis → Translation Window
  2. Go to the Settings tab
  3. Enter your API keys in the credential fields
  4. 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:
      DEEPL_API_KEY: ${{ secrets.DEEPL_API_KEY }}
      OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
      GOOGLE_TRANSLATE_API_KEY: ${{ secrets.GOOGLE_TRANSLATE_API_KEY }}
    steps:
      - uses: actions/checkout@v4
      - name: Build Unity Project
        uses: game-ci/unity-builder@v4
        with:
          projectPath: .
          targetPlatform: StandaloneWindows64

GitLab CI:

yaml
build:
  variables:
    DEEPL_API_KEY: $DEEPL_API_KEY
    OPENAI_API_KEY: $OPENAI_API_KEY
    GOOGLE_TRANSLATE_API_KEY: $GOOGLE_TRANSLATE_API_KEY
  script:
    - unity-editor -batchmode -projectPath . -buildTarget Win64

Jenkins:

groovy
pipeline {
    environment {
        DEEPL_API_KEY = credentials('deepl-api-key')
        OPENAI_API_KEY = credentials('openai-api-key')
        GOOGLE_TRANSLATE_API_KEY = credentials('google-translate-api-key')
    }
    stages {
        stage('Build') {
            steps {
                sh 'unity-editor -batchmode -projectPath . -buildTarget Win64'
            }
        }
    }
}

Docker:

dockerfile
FROM unityci/editor:ubuntu-2022.3.0f1-base

ENV DEEPL_API_KEY=""
ENV OPENAI_API_KEY=""
ENV GOOGLE_TRANSLATE_API_KEY=""

# Pass at runtime:
# docker run -e DEEPL_API_KEY=xxx -e OPENAI_API_KEY=xxx ...

Credential Lookup Order:

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

Menu: Tools → KitStack → Lexis → Translation Window

The Translation Window provides a unified interface for managing auto-translation.

Tabs

TabPurpose
TranslateTranslate strings with preview
SettingsConfigure services and credentials
MemoryView and manage translation cache

Translate Tab

  1. Service Selection: Choose DeepL, OpenAI, or Google Translate
  2. Language Selection: Source and target language dropdowns
  3. Text Input: Enter text to translate
  4. Preview: See translation result before applying
  5. Batch Translation: Translate multiple entries at once

Settings Tab

  1. Service Configuration:

    • DeepL: API key (Free or Pro), auto-detects endpoint
    • OpenAI: API key, model selection (GPT-4o, GPT-4o-mini)
    • Google: Cloud Translation API key
  2. Translation Context: Select or create a TranslationContext asset

  3. Quality Settings:

    • Enable/disable source quality checking
    • Configure AI-powered spell/grammar checking (requires OpenAI key)

Memory Tab

  1. Statistics: View cache size, entries, hit rate
  2. Search: Find cached translations
  3. Clear: Remove cached entries by language or clear all
  4. Export: Export cache for backup

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

Create: 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

FeatureOpenAI GPTDeepLGoogle Translate
Project Description✓ Full support
Genre/Audience✓ Full support
Formality✓ Full support✓ Partial*
DoNotTranslate✓ Full support
Glossary✓ 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 OpenAI.

Recommendation: For best translation quality, use OpenAI GPT with a well-configured TranslationContext. For cost-effective translations where context is less critical, 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)

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)}");

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
int removed = tm.ClearForLanguage("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("DEEPL_API_KEY"));
var result = await deepl.TranslateAsync("Hello", "en", "de");

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

// Google Translate
var google = new GoogleTranslateService(() => Environment.GetEnvironmentVariable("GOOGLE_TRANSLATE_API_KEY"));
var result = await google.TranslateAsync("Hello", "en", "de");
FeatureDeepLOpenAI GPTGoogle Translate
Languages30+All major100+
Context-awareLimitedExcellentLimited
Formality controlYesVia promptNo
Batch limit50 texts1 at a time128 texts
CostPer characterPer tokenPer character
Best forEuropean languagesCreative contentWide coverage
  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 batch translation for multiple strings to reduce API overhead
  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