using UnityEngine;
using Object = UnityEngine.Object;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Cysharp.Threading.Tasks;
using TEngine.Localization;
namespace TEngine
{
///
/// 本地化组件。
///
[DisallowMultipleComponent]
public sealed class LocalizationManager : MonoBehaviour, IResourceManager_Bundles
{
private string _defaultLanguage = "Chinese";
[SerializeField]
private TextAsset innerLocalizationCsv;
private LanguageSource _languageSource;
private LanguageSourceData _sourceData
{
get
{
if (_languageSource == null)
{
_languageSource = gameObject.AddComponent();
}
return _languageSource.SourceData;
}
}
[SerializeField]
private List allLanguage = new List();
///
/// 模拟平台运行时 编辑器资源不加载。
///
[SerializeField]
private bool useRuntimeModule = true;
private string _currentLanguage;
///
/// 获取或设置本地化语言。
///
public Language Language
{
get => LocalizationUtility.GetLanguage(_currentLanguage);
set => SetLanguage(LocalizationUtility.GetLanguageStr(value));
}
///
/// 获取系统语言。
///
public Language SystemLanguage => LocalizationUtility.SystemLanguage;
private IResourceModule _resourceModule;
///
/// 游戏框架组件初始化。
///
private void Awake()
{
_resourceModule = ModuleSystem.GetModule();
if (_resourceModule == null)
{
Log.Fatal("Resource component is invalid.");
return;
}
LocalizationModule localizationModule = new LocalizationModule();
localizationModule.Bind(this);
ModuleSystem.RegisterModule(localizationModule);
}
private void Start()
{
RootModule rootModule = RootModule.Instance;
if (rootModule == null)
{
Log.Fatal("Base component is invalid.");
return;
}
_defaultLanguage = LocalizationUtility.GetLanguageStr(
rootModule.EditorLanguage != Language.Unspecified ? rootModule.EditorLanguage : SystemLanguage);
AsyncInit().Forget();
}
private async UniTask AsyncInit()
{
if (string.IsNullOrEmpty(_defaultLanguage))
{
Log.Fatal($"Must set defaultLanguage.");
return false;
}
#if UNITY_EDITOR
if (!useRuntimeModule)
{
Localization.LocalizationManager.RegisterSourceInEditor();
UpdateAllLanguages();
SetLanguage(_defaultLanguage);
}
else
{
_sourceData.Awake();
await LoadLanguage(_defaultLanguage, true, true);
}
#else
_sourceData.Awake();
await LoadLanguage(_defaultLanguage, true, true);
#endif
return true;
}
///
/// 加载语言总表。
///
public async UniTask LoadLanguageTotalAsset(string assetName)
{
#if UNITY_EDITOR
if (!useRuntimeModule)
{
Log.Warning($"禁止在此模式下 动态加载语言");
return;
}
#endif
TextAsset assetTextAsset = await _resourceModule.LoadAssetAsync(assetName);
if (assetTextAsset == null)
{
Log.Warning($"没有加载到语言总表");
return;
}
Log.Info($"加载语言总表成功");
UseLocalizationCSV(assetTextAsset.text, true);
}
///
/// 加载语言分表。
///
/// 语言类型。
/// 是否立刻设置成当前语言。
/// 是否初始化Inner语言。
public async UniTask LoadLanguage(string language, bool setCurrent = false, bool fromInit = false)
{
#if UNITY_EDITOR
if (!useRuntimeModule)
{
Log.Warning($"禁止在此模式下 动态加载语言 {language}");
return;
}
#endif
TextAsset assetTextAsset;
if (!fromInit)
{
var assetName = GetLanguageAssetName(language);
assetTextAsset = await _resourceModule.LoadAssetAsync(assetName);
}
else
{
if (innerLocalizationCsv == null)
{
Log.Warning($"请使用I2Localization.asset导出CSV创建内置多语言.");
return;
}
assetTextAsset = innerLocalizationCsv;
}
if (assetTextAsset == null)
{
Log.Warning($"没有加载到目标语言资源 {language}");
return;
}
Log.Info($"加载语言成功 {language}");
UseLocalizationCSV(assetTextAsset.text, !setCurrent);
if (setCurrent)
{
SetLanguage(language);
}
}
private string GetLanguageAssetName(string language)
{
return $"{LocalizationUtility.I2ResAssetNamePrefix}{language}";
}
///
/// 检查并初始化所有语言的Id。
///
private void UpdateAllLanguages()
{
this.allLanguage.Clear();
List allLanguages = Localization.LocalizationManager.GetAllLanguages();
foreach (var language in allLanguages)
{
var newLanguage = Regex.Replace(language, @"[\r\n]", "");
this.allLanguage.Add(newLanguage);
}
}
///
/// 检查是否存在该语言。
///
/// 语言。
/// 是否已加载。
public bool CheckLanguage(string language)
{
return allLanguage.Contains(language);
}
///
/// 设置当前语言。
///
/// 语言名称。
/// 是否加载。
///
public bool SetLanguage(Language language, bool load = false)
{
return SetLanguage(LocalizationUtility.GetLanguageStr(language), load);
}
///
/// 设置当前语言。
///
/// 语言名称。
/// 是否加载。
///
public bool SetLanguage(string language, bool load = false)
{
if (!CheckLanguage(language))
{
if (load)
{
LoadLanguage(language, true).Forget();
return true;
}
Log.Warning($"当前没有这个语言无法切换到此语言 {language}");
return false;
}
if (_currentLanguage == language)
{
return true;
}
Log.Info($"设置当前语言 = {language}");
Localization.LocalizationManager.CurrentLanguage = language;
_currentLanguage = language;
return true;
}
///
/// 通过语言的Id设置语言。
///
/// 语言ID。
/// 是否设置成功。
public bool SetLanguage(int languageId)
{
if (languageId < 0 || languageId >= allLanguage.Count)
{
Log.Warning($"Error languageIndex. Could not set and check {languageId} Language.Count = {allLanguage.Count}.");
return false;
}
var language = allLanguage[languageId];
return SetLanguage(language);
}
private void UseLocalizationCSV(string text, bool isLocalizeAll = false)
{
_sourceData.Import_CSV(string.Empty, text, eSpreadsheetUpdateMode.Merge, ',');
if (isLocalizeAll)
{
Localization.LocalizationManager.LocalizeAll();
}
UpdateAllLanguages();
}
///
/// 语言模块加载资源接口。
///
/// 资源定位地址。
/// 资源类型。
/// 返回资源实例。
public T LoadFromBundle(string path) where T : Object
{
var assetObject = _resourceModule.LoadAsset(path);
if (assetObject != null)
{
return assetObject;
}
Log.Error($"Localization could not load {path} assetsType :{typeof(T).Name}.");
return null;
}
}
}