using System; using System.Collections.Generic; using AppUI.Localization; using TMPro; using UnityEngine; using UnityEngine.UI; /// /// AppUI Prefab 用多语言组件。行为对齐 ,但查词走 (新表优先 + 旧表回退)。 /// [ExecuteAlways] public class AppUITextAutoLanguage : MonoBehaviour { internal static readonly HashSet RegisteredComponents = new HashSet(); [SerializeField] string textKey; [Tooltip("textKey 为空时使用的明文;有 key 时仅作 Editor 预览 fallback")] [SerializeField] string fallbackText; [SerializeField] RectTransform layoutRebuildObject; public object[] textFormatArgs = { }; [SerializeField] LanguageFontSize[] languageFontSizes = {}; int defaultFontSize = -1; void Awake() { AppUILocalization.Init(); } void OnEnable() { AppUILocalization.OnLanguageChanged += HandleLanguageChanged; if (!string.IsNullOrEmpty(textKey) || !string.IsNullOrEmpty(fallbackText)) ApplyToText(); } void Start() { RegisteredComponents.Add(this); ApplyToText(); } void OnDisable() { AppUILocalization.OnLanguageChanged -= HandleLanguageChanged; } void OnDestroy() { RegisteredComponents.Remove(this); } #if UNITY_EDITOR void OnValidate() { if (string.IsNullOrEmpty(textKey) && string.IsNullOrEmpty(fallbackText)) return; ApplyToText(); } #endif void HandleLanguageChanged(LanguageEnum _) => ApplyToText(); public void SetTextKey(string key) { textKey = key; ApplyResolvedText(); } void ApplyResolvedText() { string text = ResolveDisplayText(); if (textFormatArgs != null && textFormatArgs.Length > 0) text = string.Format(text, textFormatArgs); else if (text != null && text.IndexOf("{0}", StringComparison.Ordinal) >= 0) return; Text textComp = GetComponent(); if (textComp != null) { textComp.text = text; ApplyFontSize(textComp, value => textComp.fontSize = value, value => textComp.lineSpacing = value); if (layoutRebuildObject) LayoutRebuilder.ForceRebuildLayoutImmediate(layoutRebuildObject); return; } ApplyLocalizationToTmpText(text); } string ResolveDisplayText() { if (!string.IsNullOrEmpty(textKey)) { #if UNITY_EDITOR if (!Application.isPlaying) AppUILocalization.Reload(); #endif AppUILocalization.Init(); return AppUILocalization.ResolveText(textKey); } return fallbackText ?? string.Empty; } static TMP_Text ResolveTmpTextTarget(TMP_InputField inputField, TextMeshProUGUI tmpOnSameObject) { if (inputField != null) { if (inputField.placeholder != null && inputField.placeholder is TMP_Text placeholderTmp) return placeholderTmp; if (inputField.textComponent != null) return inputField.textComponent; return tmpOnSameObject; } return tmpOnSameObject; } void ApplyLocalizationToTmpText(string text) { TMP_InputField tmpInput = GetComponent(); TextMeshProUGUI tmpUgUi = GetComponent(); TMP_Text tmpTarget = ResolveTmpTextTarget(tmpInput, tmpUgUi); if (tmpTarget == null) return; tmpTarget.text = text; ApplyFontSize(tmpTarget, value => tmpTarget.fontSize = value, value => tmpTarget.lineSpacing = value); } void ApplyFontSize(TMP_Text tmpTarget, Action setFontSize, Action setLineSpacing) { if (defaultFontSize == -1) defaultFontSize = (int)tmpTarget.fontSize; else tmpTarget.fontSize = defaultFontSize; if (languageFontSizes == null || languageFontSizes.Length == 0) return; LanguageEnum language = AppUILocalization.GetLanguage(); foreach (var languageFontSize in languageFontSizes) { if (languageFontSize.language != language) continue; if (languageFontSize.fontSize > 0) setFontSize(languageFontSize.fontSize); if (languageFontSize.lineSpacing > 0) setLineSpacing(languageFontSize.lineSpacing); break; } } void ApplyFontSize(Text textComp, Action setFontSize, Action setLineSpacing) { if (defaultFontSize == -1) defaultFontSize = textComp.fontSize; else textComp.fontSize = defaultFontSize; if (languageFontSizes == null || languageFontSizes.Length == 0) return; LanguageEnum language = AppUILocalization.GetLanguage(); foreach (var languageFontSize in languageFontSizes) { if (languageFontSize.language != language) continue; if (languageFontSize.fontSize > 0) setFontSize(languageFontSize.fontSize); if (languageFontSize.lineSpacing > 0) setLineSpacing(languageFontSize.lineSpacing); break; } } public string GetTextKey() { return textKey; } public void ApplyToText() { ApplyResolvedText(); Text text = GetComponent(); if (text) onApplyToNext?.Invoke(text); } /// Editor 刷新按钮 / 改 json 后手动调用。 public void RefreshLocalizedPreview() { #if UNITY_EDITOR if (!Application.isPlaying) AppUILocalization.Reload(); #endif ApplyToText(); } public Action onApplyToNext; }