Esta guía cubre la configuración y el uso de Unity Localization, incluyendo configuraciones regionales, tablas de cadenas y activos, integración con Addressables y soporte de fuentes CJK mediante tablas de activos.
0. Verificación de instalación del paquete
Antes de hacer cualquier otra cosa, verifica que el paquete Localization esté instalado. Muchas APIs de esta habilidad fallarán silenciosamente o lanzarán errores confusos si el paquete no está presente.
- Compruébalo leyendo el proyecto, no preguntando al Administrador de Paquetes. Busca
com.unity.localizationenPackages/packages-lock.json. Ese archivo registra lo que Unity realmente resolvió, es JSON plano, y leerlo no necesita Editor ni llamada asíncrona. (Packages/manifest.jsonsolo registra lo que se solicitó, así que revisa el archivo de bloqueo). - Instala si falta:
UnityEditor.PackageManager.Client.Add("com.unity.localization"). - Espera correctamente.
Client.AddyClient.Listson asíncronos: devuelven una solicitud que aún estáInProgresscuando la llamada regresa, por lo que leer el resultado en la misma declaración no te dice nada. Tampoco hagas espera activa enIsCompleted; eso bloquea el hilo principal en el que te estás ejecutando. En su lugar, devuelve el control después de iniciar la instalación, luego sondeapackages-lock.jsonen una llamada posterior hasta que aparezca el ID. La instalación también desencadena un reinicio de dominio, así que espera que el primer o segundo sondeo fallen; una instalación nueva suele resolverse en unos segundos. - Confirma que los tipos realmente se hayan cargado antes de usarlos, ya que el archivo de bloqueo puede escribirse antes de que los ensamblados estén listos:
Solo continúa cuando eso devuelvavar t = System.Type.GetType( "UnityEngine.Localization.Settings.LocalizationSettings, Unity.Localization"); return t != null ? "ready" : "not loaded yet";ready.
1. Configuración de localización y configuraciones regionales
Si LocalizationEditorSettings.ActiveLocalizationSettings es nulo, debes encontrarlo o crearlo:
- Encontrar: Usa
AssetDatabase.FindAssets("t:LocalizationSettings", new[] { "Assets" }). Si se encuentra, carga el primero y asígnalo aLocalizationEditorSettings.ActiveLocalizationSettings.- Siempre pasa las carpetas de búsqueda. Un
FindAssetssin ámbito busca en todo el proyecto, incluidos paquetes de solo lectura, por lo que podría devolver un activo de un paquete y terminar apuntando el proyecto a algo que no puedes editar. Esto aplica a cada llamadaFindAssetsen esta habilidad.
- Siempre pasa las carpetas de búsqueda. Un
- Crear: Si no se encuentra, crea una nueva instancia y guárdala en
Assets/Localization/LocalizationSettings.asset. UsaScriptableObject.CreateInstance<LocalizationSettings>()seguido deAssetDatabase.CreateAsset(). - Activar: Establece
LocalizationEditorSettings.ActiveLocalizationSettings = settings. - Configuraciones regionales: Asegúrate de que existan configuraciones regionales (es, fr, de, etc.). Créalas si faltan y agrégalas a la configuración usando
LocalizationEditorSettings.AddLocale(locale).
2. Modificación de tablas de localización
Los cambios programáticos en tablas de cadenas o activos requieren notificación al Editor. Siempre crea las tablas de activos necesarias, a menos que ya exista una en el proyecto.
Patrón de población seguro
Al poblar tablas desde un conjunto de datos, empareja explícitamente por Locale.Identifier.Code. El orden de GetLocales() no está garantizado para coincidir con tu arreglo de datos de entrada, y asumir que lo hace causará discrepancias de datos silenciosas que son muy difíciles de depurar.
Para Tablas de Activos, usa el GUID del activo: table.GetEntry(sharedId) ?? table.AddEntry(sharedId, guid);.
Actualización y notificación
Después de cualquier modificación (agregar claves, actualizar valores), notifica al Editor para que pueda actualizar su estado interno. Omitir esto dejará al Editor mostrando datos obsoletos hasta la próxima reimportación.
- Llama a
EditorUtility.SetDirty(collection),EditorUtility.SetDirty(collection.SharedData), en cadaTablemodificada. - Notificación en Unity 6+:
LocalizationEditorSettings.EditorEvents.RaiseCollectionModified(sender, collection); - Siempre llama a
AssetDatabase.SaveAssets()al final.
3. Localización de la interfaz de usuario y diseño
Espacios de nombres y conflictos
- Siempre califica los nombres: Usa
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.UIes tanto un espacio de nombres como un contenedor de clases, por lo que los nombres no calificados producenCS0118(espacio de nombres usado como tipo). La calificación completa evita esto por completo.- Instancia única: Siempre verifica
GameObject.Find("YourCanvasName")y destruye el anterior antes de crear uno nuevo. - Cambio de configuración regional: usa el paquete, y mantén separados vista previa y tiempo de ejecución. Estos son dos mecanismos diferentes, y confundirlos es la razón por la que el cambio de configuración regional a menudo termina hecho a mano.
- Para previsualizar una configuración regional mientras se autoriza, usa la ventana Localization Scene Controls (
Window > Asset Management > Localization Scene Controls). Esto es solo para el Editor. No es una función de tiempo de ejecución, por lo que no es la respuesta cuando el juego necesita una configuración de idioma. - Para cambiar la configuración regional en tiempo de ejecución, asigna
LocalizationSettings.SelectedLocale. Ese es el punto de entrada compatible, y todo lo vinculado a través deLocalizeStringEventse actualiza a partir de él. - Para fijar con qué configuración regional comienza el juego, configura un selector de configuración regional de inicio en el activo de Configuración de Localización.
SpecificLocaleSelectores el que fuerza una configuración regional elegida; la cadena predeterminada, de lo contrario, toma el idioma del sistema. - NUNCA implementes manualmente el estado de configuración regional. Un menú de idioma real dentro del juego está bien y es esperado, siempre que establezca
SelectedLocaley permita que el paquete propague el cambio. Lo que está prohibido es un menú desplegable de depuración o un menú que rastrea su propia variable "idioma actual", intercambia cadenas por sí mismo, o evita el paquete, porque nada más en el proyecto lo seguirá.
- Para previsualizar una configuración regional mientras se autoriza, usa la ventana Localization Scene Controls (
Eventos de cadena localizada (enlace robusto)
-
Verifica el tipo de componente: Identifica si el objetivo es
TextMeshProo elUnityEngine.UI.Textheredado. -
Enlaza correctamente: agrega el componente público
UnityEngine.Localization.Components.LocalizeStringEventy conéctalo tú mismo: estableceStringReferenceen la entrada de la tabla, luego agrega un oyenteOnUpdateStringque asigna el valor al componente de texto (TMP_Text.textpara TextMeshPro,UnityEngine.UI.Text.textpara Text heredado).No uses reflexión en
UnityEditor.Localization.Plugins.TMPro.LocalizeComponent_TMProo su contraparte para UGUI. Esos soninternal(medido en Localization 1.5.12), por lo que acceder a ellos significa sortear el control de acceso para alcanzar una API sobre la que Unity no hace ningún compromiso de estabilidad: puede cambiar o desaparecer en cualquier versión del paquete.LocalizeStringEventes público y hace el mismo trabajo con la conexión hecha explícita. -
Reconstrucción de diseño: Después de establecer el texto localizado o poblar una lista, llama a
UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(parentTransform)para asegurar que las dimensiones se actualicen.
4. Soporte de fuentes para idiomas asiáticos (CJK)
Evita las Fuentes de Fallback TMP para configuraciones regionales CJK. Usa Intercambio de Fuentes con Tabla de Activos para cada configuración regional específica en su lugar: los fallbacks no son confiables y son difíciles de depurar cuando faltan glifos.
Requisito previo: los Recursos Esenciales de TMP deben estar importados
Verifica esto antes de tocar cualquier API de TMP. En un proyecto que nunca los ha importado, TMP_Settings.instance es null y las llamadas a TMP fallan con una NullReferenceException que no nombra nada útil. TMP_FontAsset.CreateFontAsset es una de ellas, por lo que la creación de fuentes muere en la primera línea con un error.