Skip to content
Development
Skill

/localization

Sets up and configures Unity Localization, including locales, String and Asset Tables, and CJK fonts. Use when the user asks to add languages, translate UI text, or mentions i18n or multilingual support.

BOOST
From plugin
unity-technologies-skills
1.1k34 skills
Install
$ npx -y skills add unity-technologies/skills --skill localization --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/localization

Context preview

The summary Claude sees to decide when to auto-load this skill.

Sets up and configures Unity Localization, including locales, String and Asset Tables, and CJK fonts. Use when the user asks to add languages, translate UI text, or mentions i18n or multilingual support.

SKILL.md

localization.SKILL.md
name: localization
description: Sets up and configures Unity Localization, including locales, String and Asset Tables, and CJK fonts. Use when the user asks to add languages, translate UI text, or mentions i18n or multilingual support.

This guide covers setting up and configuring Unity Localization, including locales, String and Asset Tables, Addressables integration, and CJK font support via Asset Tables.

0. Package Installation Check

Before doing anything else, verify that the Localization package is installed. Many APIs in this skill will fail silently or throw confusing errors if the package isn't present.

1. **Check by reading the project, not by asking the Package Manager.** Look for `com.unity.localization` in **`Packages/packages-lock.json`**. That file records what Unity actually resolved, it is plain JSON, and reading it needs no Editor and no async call. (`Packages/manifest.json` only records what was *requested*, so check the lock file.) 2. **Install if missing:** `UnityEditor.PackageManager.Client.Add("com.unity.localization")`. 3. **Wait properly.** `Client.Add` and `Client.List` are **asynchronous**: they return a request that is still `InProgress` when the call returns, so reading the result in the same statement tells you nothing. Do not busy-wait on `IsCompleted` either; that blocks the main thread you are running on. Instead, return after firing the install, then **poll `packages-lock.json` in a later call** until the id appears. Installation also triggers a domain reload, so expect the first poll or two to fail; a fresh install typically resolves in a few seconds. 4. **Confirm the types are actually loaded** before using them, since the lock file can be written before the assemblies are ready:

   var t = System.Type.GetType(
       "UnityEngine.Localization.Settings.LocalizationSettings, Unity.Localization");
   return t != null ? "ready" : "not loaded yet";

Only proceed once that returns `ready`.

1. Localization Settings & Locales

If `LocalizationEditorSettings.ActiveLocalizationSettings` is null, you must find or create it: 1. **Find:** Use `AssetDatabase.FindAssets("t:LocalizationSettings", new[] { "Assets" })`. If found, load the first one and assign it to `LocalizationEditorSettings.ActiveLocalizationSettings`.

  • **Always pass the search folders.** An unscoped `FindAssets` searches the whole project including

read-only packages, so it can return an asset from a package and you end up pointing the project at something you cannot edit. This applies to every `FindAssets` call in this skill. 2. **Create:** If not found, create a new instance and save it to `Assets/Localization/LocalizationSettings.asset`. Use `ScriptableObject.CreateInstance<LocalizationSettings>()` followed by `AssetDatabase.CreateAsset()`. 3. **Activate:** Set `LocalizationEditorSettings.ActiveLocalizationSettings = settings`. 4. **Locales:** Ensure locales (en, fr, de, etc.) exist. Create them if missing and add them to settings using `LocalizationEditorSettings.AddLocale(locale)`.

2. Modifying Localization Tables

Programmatic changes to String or Asset tables require notification to the Editor. Always create the required asset tables, unless there is already an existing one in the project.

**Safe Population Pattern**

When populating tables from a dataset, match by `Locale.Identifier.Code` explicitly. The order of `GetLocales()` is not guaranteed to match your input data array — assuming it does will cause silent data mismatches that are very hard to debug. For **Asset Tables**, use the GUID of the asset: `table.GetEntry(sharedId) ?? table.AddEntry(sharedId, guid);`.

**Refresh & Notification**

After any modification (adding keys, updating values), notify the Editor so it can refresh its internal state. Skipping this will leave the Editor showing stale data until the next reimport. 1. Call `EditorUtility.SetDirty(collection)`, `EditorUtility.SetDirty(collection.SharedData)`, on each modified `Table`. 2. **Unity 6+ Notification:** `LocalizationEditorSettings.EditorEvents.RaiseCollectionModified(sender, collection);` 3. Always call `AssetDatabase.SaveAssets()` at the end.

3. UI Localization and Layout

**Namespacing & Conflicts**

  • **Always qualify names:** Use `UnityEngine.UI.Image`, `UnityEngine.UI.VerticalLayoutGroup`, `UnityEngine.UI.ScrollRect`, `UnityEngine.UI.Mask`, `UnityEngine.UI.CanvasScaler`, `UnityEngine.UI.GraphicRaycaster`, `UnityEngine.UI.ContentSizeFitter`, `UnityEngine.UI.LayoutRebuilder`, etc.
  • `UnityEngine.UI` is both a namespace and a class container, so unqualified names produce `CS0118` (namespace used like a type). Full qualification avoids this entirely.
  • **Single Instance:** Always check `GameObject.Find("YourCanvasName")` and destroy the old one before creating a new one.
  • **Locale switching: use the package, and keep preview and runtime separate.** These are two

different mechanisms, and conflating them is why locale switching often ends up hand-rolled.

  • **To preview a locale while authoring**, use the **Localization Scene Controls** window

(`Window > Asset Management > Localization Scene Controls`). This is Editor-only. It is not a runtime feature, so it is not the answer when the game itself needs a language setting.

  • **To switch locale at runtime**, assign `LocalizationSettings.SelectedLocale`. That is the

supported entry point, and everything bound through `LocalizeStringEvent` updates from it.

  • **To pin which locale the game starts in**, configure a startup locale selector on the

Localization Settings asset. `SpecificLocaleSelector` is the one that forces a chosen locale; the default chain otherwise picks up the system language.

  • **NEVER hand-roll locale state.** A real in-game language menu is fine and expected, as long as

it sets `SelectedLocale` and lets the package propagate the change. What is forbidden is a debug drop

Read more
Ships withunity-technologies-skills

A collection of reusable AI agent skills for Unity workflows. Compatible with Claude Code, GitHub Copilot, Cursor, Cline, and 50+ other agents.

Get the whole plugin

Other skills on unity-technologies-skills.