Unity's localization package is integrated with UI Toolkit.

Luna UI provides demos, guidelines, and utility functions for using Unity's Localization package.

Luna provides the runtime pieces for locale-driven styling: the LocalizationViewStyleSwitcher component, the Essentials theme's .locale-ja font hook in LocalizedStyles.uss, and a bundled Japanese SDF font (Dela Gothic One). Wiring up Unity's Localization package itself — adding Locales, creating String Tables, and authoring LocalizedString bindings — is your job. The First-time setup walkthrough below covers that path end to end, and the Google Sheets sync tool automates the table-management side. Luna does not ship a pre-wired end-to-end localization demo scene or any string-table data.

Unity Localization: UI Toolkit

First-time setup

Localization setup is a one-time, project-level task — and it's all stock com.unity.localization, so the menus below are Unity's, not Luna's. The official Quick Start Guide is the canonical reference; here's the short version.

Prerequisite: install Localization (com.unity.localization) from the Package Manager (Unity Registry). The GameFull sample already lists it as a dependency.

  1. Create the Localization Settings asset. Go to Edit > Project Settings > Localization and click Create. This writes a LocalizationSettings asset and registers it as the project's active settings. Until it exists, the localization APIs no-op — and the in-game language switcher shows a disabled "Localization Not Configured".

  2. Add Locales. From the Localization Settings page, open the Locale Generator, tick the languages you want (e.g. English, Japanese), and Add Locales. Each becomes a Locale asset. Set a default under Locale Selectors if you want a guaranteed startup language.

  3. Create a String Table Collection. Open Window > Asset Management > Localization Tables, choose New Table Collection > String Table Collection, name it (e.g. UI Text), tick the locales to include, and Create. Unity generates one String Table per locale.

  4. Add entries. In the Localization Tables window, add a row per string: a Key (a stable id like menu.play) plus the translation in each locale column. To fill or maintain large tables from a spreadsheet instead of by hand, see Bulk-syncing String Tables with Google Sheets below.

  5. Bind a LocalizedString. Point a UI element at a table + entry. The UI Builder workflow in UI Builder authoring below is the fastest path; you can also assign a LocalizedString field in C#.

That's the full loop. Add a LocalizationViewStyleSwitcher if you also need locale-specific fonts at runtime.

Guide

UI Builder authoring

You can use the UI Builder to create and fine-tune UI assets and their associated data bindings, including localization data bindings. You can connect to visual element attribute fields or styles. You can also address mismatched data types smoothly by creating your own converters for data type conversion.

To bind an element's field to a localized value in UI Builder, do the following:

  1. In the Inspector panel of an element, right-click on a field and select Add binding.

Adding a binding through the UI Builder.

  1. In the Add binding window, select the type of binding you want to use.

Add binding window type popup showing localization binding types.

  1. To set up the binding, specify the table and entry you want to reference. If you're using a LocalizedString binding and want to include local variables, you can do so through the Variables field.

Configuring a localized string in the Add binding window.

Warning: By default, the table and entry are referenced using the Guid and ID. To customize this behavior, go to Edit > Preferences > Localization and adjust the Table Reference Method and Entry Reference Method options.

The UI builder-generated UXML includes the new localized string binding like this:

xml
<ui:UXML xmlns:ui="UnityEngine.UIElements"> <ui:Label text="Label"> <Bindings> <UnityEngine.Localization.LocalizedString property="text" table="General Test Data" entry="My Entry"> <variables> <UnityEngine.Localization.LocalVariable name="counter"> <UnityEngine.Localization.SmartFormat.PersistentVariables.IntVariable value="2" /> </UnityEngine.Localization.LocalVariable> </variables> </UnityEngine.Localization.LocalizedString> </Bindings> </ui:Label> </ui:UXML>

Bulk-syncing String Tables with Google Sheets

com.cupkekgames.localization is an editor-only helper that automates Unity Localization's Google Sheets integration: it connects every String Table Collection in your project to a shared spreadsheet, so translators can work in Google Sheets while you push and pull with one click. It builds directly on Unity's official GoogleSheetsExtension — the synced data is plain Unity String Tables, nothing proprietary.

Prefer flat files? Unity Localization also ships a native CSV import/export extension. This package targets the Google Sheets workflow specifically.

The setup config asset

Create one via Assets > Create > Localization > Setup Config (a LocalizationSetupConfig ScriptableObject). Its fields:

FieldPurpose
Google Sheets Service ProviderUnity Localization's SheetsServiceProvider asset, holding your Google API credentials. Required for any push/pull.
Spreadsheet IdThe target Google Sheet's id (copy it from the sheet's URL).
Key ColumnSpreadsheet column holding the entry keys (default A).
Table CollectionsOne row per StringTableCollection paired with its Sheet ID (the tab inside the spreadsheet). Usually auto-filled — see below.
Locale ColumnsOne row per locale: a column letter (default B) → a Locale, plus an optional Comments column. This is the CSV-style layout — a key column plus one column per language.
Remove Missing Pulled KeysOn pull, delete local keys that no longer exist in the sheet (default on).

The inspector buttons

The custom inspector exposes a guided, numbered workflow:

  • Run All Setup — runs steps 1–4 in order; the one-click path once the service provider and spreadsheet id are set.
    1. Find Tables — scans the project for every StringTableCollection and fills the Table Collections list.
    2. Create Missing — for each collection, adds a String Table for any project Locale that's missing one. (Add your Locales first — see First-time setup.)
    3. Setup Sheet IDs — connects to Google, matches each collection name to a sheet tab (creating the tab if it doesn't exist), and records its Sheet ID.
    4. Apply Config — writes a configured GoogleSheetsExtension onto each collection (service provider, spreadsheet id, sheet id, key + locale columns, remove-missing flag).
  • Push All / Pull All — push your local tables up to Sheets, or pull Sheets back into your String Tables, across every configured collection.
  • Per-Table Operations — the same actions (All / Missing / Sheet / Config, plus Push / Pull) scoped to a single collection, for incremental work.

A typical first run: assign the service provider and spreadsheet id → Run All SetupPush All to seed the sheet → translators edit in Google Sheets → Pull All to bring translations back.

Buttons that talk to Google stay disabled until both Google Sheets Service Provider and Spreadsheet Id are set; Create Missing only needs Locales and tables. See Unity's Google Sheets docs for creating the service provider and authorizing API access.

In-game language switcher

com.cupkekgames.settings ships a ready-made language picker — SettingsMenuViewGameplay (namespace CupkekGames.Settings.UI). Put a DropdownField named DropdownLanguage in your settings UXML (GameFull's SettingsGameFull.uxml has one) and the view populates and drives it for you.

What the dropdown shows depends on how far localization is wired:

Project stateDropdown
com.unity.localization not installed"Localization Package Not Installed" (placeholder)
Installed, but no LocalizationSettings assetdisabled "Localization Not Configured"
Configured, but zero Localesdisabled "No Locales Available"
Configured with Localesone entry per available Locale (native language name), with the active locale preselected

The "Localization Not Configured" state is the important one. It's guarded by a LocalizationSettings.HasSettings check: without it, querying the selected locale on a project that has the package but no settings asset faults the initialization operation and floods the console on every settings-apply. The switcher detects that case and degrades to a clear, disabled label instead.

When the player picks a language, the view writes the chosen LocaleIdentifier into the settings' Localization section and calls SettingsSystem.ScheduleApplySelectedLocale(...), which waits for localization to initialize and then sets LocalizationSettings.SelectedLocale. That change fires SelectedLocaleChanged, which the LocalizationViewStyleSwitcher below uses to swap locale-specific fonts. The selection persists with the rest of the settings (PlayerPrefs) and is reapplied on load.

Luna UI Runtime Style Switching

Luna UI provides LocalizationViewStyleSwitcher component that enables runtime font and style switching based on the active locale. This works around Unity's limitation of not being able to change global USS variables at runtime by applying locale-specific USS classes to all UIViews.

Setup

Add the LocalizationViewStyleSwitcher component to a GameObject in your scene (typically on the same GameObject as your LunaUIManager).

Configuration

Locale Class Prefix

The _localeClassPrefix field determines the prefix used for locale-specific USS classes. The default value is "locale-". The component automatically generates class names based on the active locale. For example, with the default prefix, it generates classes like locale-en, locale-zh-cn, and locale-ja.

How It Works

When the locale changes, LocalizationViewStyleSwitcher:

  1. Removes the previous locale class from all UIViews using LunaUIManager.RemoveClassFromAllUIViews()
  2. Adds the new locale class to all UIViews using LunaUIManager.AddClassToAllUIViews()

The component automatically subscribes to LocalizationSettings.SelectedLocaleChanged and applies the appropriate locale class whenever the locale changes.

USS Class Structure

Create locale-specific styles in your USS files using the generated class names. You can override USS custom properties (CSS variables) for locale-specific fonts.

The shipped .locale-ja block lives in the Essentials theme's LocalizedStyles.uss. Only the Japanese locale is covered — switching to Japanese swaps in a glyph-capable SDF font via the .locale-ja class. The snippet below is an illustrative pattern for your own theme copy.

⚠️ Don't copy the url() paths verbatim. A USS url() is resolved relative to the file it lives in, so the font path depends on your USS file's folder depth — paste it unchanged and the font silently fails to load. The shipped .locale-ja block uses url("Fonts/dela-gothic-one/static/DelaGothicOne-RegularSDF.asset"), which resolves correctly because LocalizedStyles.uss sits in the Essentials Theme/ folder and the font lives beneath it at Theme/Fonts/dela-gothic-one/static/. Adjust the path to wherever your USS sits relative to the fonts.

css
/* Japanese locale - uses custom font */ .locale-ja { --font-black: url("Fonts/dela-gothic-one/static/DelaGothicOne-RegularSDF.asset"); --font-black-italic: url("Fonts/dela-gothic-one/static/DelaGothicOne-RegularSDF.asset"); --font-bold: url("Fonts/dela-gothic-one/static/DelaGothicOne-RegularSDF.asset"); --font-bold-italic: url("Fonts/dela-gothic-one/static/DelaGothicOne-RegularSDF.asset"); --font-light: url("Fonts/dela-gothic-one/static/DelaGothicOne-RegularSDF.asset"); --font-light-italic: url("Fonts/dela-gothic-one/static/DelaGothicOne-RegularSDF.asset"); --font-medium: url("Fonts/dela-gothic-one/static/DelaGothicOne-RegularSDF.asset"); --font-medium-italic: url("Fonts/dela-gothic-one/static/DelaGothicOne-RegularSDF.asset"); }

You can add similar styles for other locales (e.g., .locale-en, .locale-zh-cn) as needed.

For more details, see Global UIView Registry.

AutoSizeText with Localization

Auto-sizing text is particularly useful for localization, as different languages have varying text lengths. See Auto Size Text for detailed information on auto-sizing text in UI Toolkit.

Settings

Theme

Light

Contrast

Material

Dark

Dim

Material Dark

System

Sidebar(Light & Contrast only)

Light
Dark

Font Family

DM Sans

Wix

Inclusive Sans

AR One Sans

Direction

LTR
RTL