using AibisDream.Kit;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace AibisDream.Framework
{
///
/// csv 本地化列类别。集中声明"哪些 Locale 归到哪一列",csv 数据类按此枚举取字段。
///
public enum LocaleKind
{
Cn,
En,
Ja
}
public static class LocalizationKit
{
private const string LocalizationPrefix = "l10n.";
public static string CurrentLanguageCode { get; private set; } = "zh-Hans";
public static Locale CurrentLocale => LocalizationSettings.SelectedLocale;
///
/// 把 LocaleCode 映射到 csv 列类别。集中在此一处,便于扩展(加新语言时修改这里 + LocaleKind 枚举 + 数据类字段)。
///
public static LocaleKind GetLocaleKind(string localeCode)
{
if (string.IsNullOrEmpty(localeCode)) return LocaleKind.Cn;
if (localeCode.StartsWith("en")) return LocaleKind.En;
if (localeCode.StartsWith("ja")) return LocaleKind.Ja;
return LocaleKind.Cn;
}
public static LocaleKind CurrentLocaleKind => GetLocaleKind(CurrentLanguageCode);
///
/// 解析 setting.json 中的 Language:空值表示跟随系统语言,否则使用用户保存的 code。
///
public static string ResolveLanguage(string savedLanguage)
{
if (!string.IsNullOrWhiteSpace(savedLanguage))
{
return savedLanguage.Trim();
}
return MapSystemLanguage(Application.systemLanguage);
}
///
/// 将 Unity 系统语言映射到项目支持的 Locale code。
///
public static string MapSystemLanguage(SystemLanguage lang) => lang switch
{
SystemLanguage.Chinese or SystemLanguage.ChineseSimplified or SystemLanguage.ChineseTraditional => "zh-Hans",
SystemLanguage.Japanese => "ja-JP",
SystemLanguage.English => "en",
_ => "en",
};
static LocalizationKit()
{
#if UNITY_EDITOR
EditorApplication.playModeStateChanged += OnPlayModeChanged;
#else
LocalizationSettings.SelectedLocaleChanged += OnLocaleChanged;
RefreshCurrentLanguageCodeAsync();
#endif
}
private static void OnLocaleChanged(Locale locale)
{
UpdateCurrentLanguageCode(locale);
EnumEventSystem.Global.Send(SettingChangeEvent.LocaleChanged, locale);
}
private static void UpdateCurrentLanguageCode(Locale locale)
{
if (locale != null)
{
CurrentLanguageCode = locale.Identifier.Code;
}
}
private static async void RefreshCurrentLanguageCodeAsync()
{
await LocalizationSettings.InitializationOperation.Task;
UpdateCurrentLanguageCode(LocalizationSettings.SelectedLocale);
}
#if UNITY_EDITOR
private static void OnPlayModeChanged(PlayModeStateChange playMode)
{
if (playMode == PlayModeStateChange.EnteredPlayMode)
{
LocalizationSettings.SelectedLocaleChanged += OnLocaleChanged;
RefreshCurrentLanguageCodeAsync();
}
else if (playMode == PlayModeStateChange.ExitingPlayMode)
{
LocalizationSettings.SelectedLocaleChanged -= OnLocaleChanged;
}
}
#endif
public static async void SwitchLanguage(string localeCode)
{
// 等待本地化系统初始化完成
await LocalizationSettings.InitializationOperation.Task;
var selectedLocale =
LocalizationSettings.AvailableLocales.Locales.Find(locale => locale.Identifier.Code == localeCode);
if (selectedLocale)
{
LocalizationSettings.SelectedLocale = selectedLocale;
}
else
{
Debug.LogWarning($"Locale with code {localeCode} not found.");
}
}
///
/// 本地化参数
///
/// 参数名
///
public static string LocalizeParam(string param)
{
// 非本地化参数直接返回
if (string.IsNullOrEmpty(param)) return param;
if (!param.StartsWith(LocalizationPrefix)) return param;
var localizationKey = param[LocalizationPrefix.Length..];
if (ConfigUtil.Instance.TryGetParam(localizationKey, out var value))
{
return value.LocalizeByKind(CurrentLocaleKind);
}
// 如果找不到,则使用原始值
Debug.LogWarning($"Variable Key '{localizationKey}' not found in params csv.");
return localizationKey;
}
public static string GetL10NParamKey(string key)
{
// 本地化参数则去除前缀,非本地化参数直接返回
return key.StartsWith(LocalizationPrefix) ? key[LocalizationPrefix.Length..] : key;
}
///
/// 确保本地化系统已初始化
///
/// 初始化操作
public static async void EnsureInitialized()
{
await LocalizationSettings.InitializationOperation.Task;
}
}
}