| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- using System;
- using System.Collections.Generic;
- using AppUI.Localization;
- using TMPro;
- using UnityEngine;
- using UnityEngine.UI;
- /// <summary>
- /// AppUI Prefab 用多语言组件。行为对齐 <see cref="TextAutoLanguage2"/>,但查词走 <see cref="AppUILocalization"/>(新表优先 + 旧表回退)。
- /// </summary>
- [ExecuteAlways]
- public class AppUITextAutoLanguage : MonoBehaviour
- {
- internal static readonly HashSet<AppUITextAutoLanguage> RegisteredComponents = new HashSet<AppUITextAutoLanguage>();
- [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<Text>();
- 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<TMP_InputField>();
- TextMeshProUGUI tmpUgUi = GetComponent<TextMeshProUGUI>();
- 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<float> setFontSize, Action<float> 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<int> setFontSize, Action<float> 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<Text>();
- if (text)
- onApplyToNext?.Invoke(text);
- }
- /// <summary>Editor 刷新按钮 / 改 json 后手动调用。</summary>
- public void RefreshLocalizedPreview()
- {
- #if UNITY_EDITOR
- if (!Application.isPlaying)
- AppUILocalization.Reload();
- #endif
- ApplyToText();
- }
- public Action<Text> onApplyToNext;
- }
|