182 lines
5.1 KiB
C#
182 lines
5.1 KiB
C#
using System.Collections;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.Localization.Components;
|
|
using UnityEngine.SceneManagement;
|
|
using UnityEngine.UI;
|
|
using System.Collections.Generic;
|
|
|
|
public class LocalizationRuntimeBootstrap : MonoBehaviour
|
|
{
|
|
private static LocalizationRuntimeBootstrap _instance;
|
|
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
|
private static void Bootstrap()
|
|
{
|
|
LocalizationService.EnsureInitialized();
|
|
if (_instance != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GameObject go = new GameObject("LocalizationRuntimeBootstrap");
|
|
DontDestroyOnLoad(go);
|
|
_instance = go.AddComponent<LocalizationRuntimeBootstrap>();
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
if (_instance != null && _instance != this)
|
|
{
|
|
Destroy(gameObject);
|
|
return;
|
|
}
|
|
|
|
_instance = this;
|
|
SceneManager.sceneLoaded += OnSceneLoaded;
|
|
LocalizationService.LanguageChanged += OnLanguageChanged;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
StartCoroutine(ApplyLocalizationDeferred());
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (_instance == this)
|
|
{
|
|
SceneManager.sceneLoaded -= OnSceneLoaded;
|
|
LocalizationService.LanguageChanged -= OnLanguageChanged;
|
|
_instance = null;
|
|
}
|
|
}
|
|
|
|
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
|
{
|
|
StartCoroutine(ApplyLocalizationDeferred());
|
|
}
|
|
|
|
private void OnLanguageChanged(string languageCode)
|
|
{
|
|
StartCoroutine(ApplyLocalizationDeferred());
|
|
}
|
|
|
|
private IEnumerator ApplyLocalizationDeferred()
|
|
{
|
|
// Some UI updates its text in Start/OnEnable one or two frames after scene load.
|
|
// Re-apply for a few frames so late-bound labels are still captured.
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
yield return null;
|
|
ApplyLocalizationToLoadedTexts();
|
|
}
|
|
}
|
|
|
|
private static void ApplyLocalizationToLoadedTexts()
|
|
{
|
|
foreach (Text text in EnumerateSceneTexts())
|
|
{
|
|
if (!IsLocalizable(text))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
LocalizedLiteralText binding = text.GetComponent<LocalizedLiteralText>();
|
|
if (binding == null)
|
|
{
|
|
binding = text.gameObject.AddComponent<LocalizedLiteralText>();
|
|
}
|
|
|
|
binding.CaptureIfNeeded(text.text, false);
|
|
binding.Refresh();
|
|
}
|
|
|
|
foreach (TMP_Text tmp in EnumerateSceneTmpTexts())
|
|
{
|
|
if (!IsLocalizable(tmp))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
LocalizedLiteralText binding = tmp.GetComponent<LocalizedLiteralText>();
|
|
if (binding == null)
|
|
{
|
|
binding = tmp.gameObject.AddComponent<LocalizedLiteralText>();
|
|
}
|
|
|
|
binding.CaptureIfNeeded(tmp.text, true);
|
|
binding.Refresh();
|
|
}
|
|
}
|
|
|
|
private static IEnumerable<Text> EnumerateSceneTexts()
|
|
{
|
|
int sceneCount = SceneManager.sceneCount;
|
|
for (int i = 0; i < sceneCount; i++)
|
|
{
|
|
Scene scene = SceneManager.GetSceneAt(i);
|
|
if (!scene.IsValid() || !scene.isLoaded)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
GameObject[] roots = scene.GetRootGameObjects();
|
|
for (int rootIndex = 0; rootIndex < roots.Length; rootIndex++)
|
|
{
|
|
Text[] texts = roots[rootIndex].GetComponentsInChildren<Text>(true);
|
|
for (int textIndex = 0; textIndex < texts.Length; textIndex++)
|
|
{
|
|
yield return texts[textIndex];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static IEnumerable<TMP_Text> EnumerateSceneTmpTexts()
|
|
{
|
|
int sceneCount = SceneManager.sceneCount;
|
|
for (int i = 0; i < sceneCount; i++)
|
|
{
|
|
Scene scene = SceneManager.GetSceneAt(i);
|
|
if (!scene.IsValid() || !scene.isLoaded)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
GameObject[] roots = scene.GetRootGameObjects();
|
|
for (int rootIndex = 0; rootIndex < roots.Length; rootIndex++)
|
|
{
|
|
TMP_Text[] texts = roots[rootIndex].GetComponentsInChildren<TMP_Text>(true);
|
|
for (int textIndex = 0; textIndex < texts.Length; textIndex++)
|
|
{
|
|
yield return texts[textIndex];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static bool IsLocalizable(Component component)
|
|
{
|
|
if (component == null || component.gameObject == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
GameObject gameObject = component.gameObject;
|
|
if (!gameObject.scene.IsValid() || !gameObject.scene.isLoaded || string.IsNullOrEmpty(gameObject.scene.name))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (gameObject.GetComponent<LocalizedText>() != null ||
|
|
gameObject.GetComponent<LocalizedTMPText>() != null ||
|
|
gameObject.GetComponent<LocalizeStringEvent>() != null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|