/* * @Author: 白哉 * @Description: * @Date: 2025年05月26日 星期一 14:05:50 * @Modify: */ using System.Collections.Generic; using System.Text.RegularExpressions; using TMPro; using UnityEngine; namespace Logic.Multilingual { [DisallowMultipleComponent] public class MultilingualTextMono : MonoBehaviour { public bool Ban; public bool NoExport = false; public bool FontBan = false; // 全局文本样式预设:让多个 TMP 共享一套多语言字号/行距方案 // None=不使用预设,仅依赖 TextCfg 里的 override(保持原有行为) // 三级 fallback 优先级:TextCfg 命中 > Preset 命中 > 不动 public TH1_DataAssetsScript.TextStylePreset Preset = TH1_DataAssetsScript.TextStylePreset.None; [HideInInspector] public uint ID = 0; [HideInInspector] public uint FontID = 0; [HideInInspector] public List TextCfg = new List(); private List _paramList; public MultilingualType PreviewType { get => _previewType; set => _previewType = value; } private MultilingualType _previewType = MultilingualType.ZH; public List ParamList { get => _paramList ??= new List(); set => _paramList = value; } private void OnEnable() { OnMultilingualChanged(); } public void OnMultilingualChanged() { var text = GetComponent(); if (!text) return; if (!FontBan) { BindFontID(); if (FontID != 0) { var font = MultilingualManager.Instance.GetMultilingualFont(FontID); if (font)text.font = font; MatchTextCfg(text, MultilingualManager.Instance.CurrentType); } } if (!Ban) { if (ID != 0) text.text = MultilingualManager.Instance.GetMultilingualText(ID); if (_paramList != null && _paramList.Count != 0) { int index = 0; text.text = Regex.Replace(text.text, "{param}", m => index < _paramList.Count ? _paramList[index++] : m.Value); } ApplyDefaultEmbeddedColor(text); // RTL 方向切换:阿语/希伯来语开 RTL,其他语言关掉。 // 注意:仅控制字符排列方向,不做 shaping(字母连写);连写需第三方库 ArabicFixer 预处理字符串。 ApplyRTLDirection(text, MultilingualManager.Instance.CurrentType); } } // 仅阿拉伯语 / 希伯来语开启 TMP 内置 RTL;其他语言显式关掉, // 避免切语言时阿语切走后 isRightToLeftText 残留导致下一种语言反向显示 private static void ApplyRTLDirection(TextMeshProUGUI text, MultilingualType type) { text.isRightToLeftText = (type == MultilingualType.AR || type == MultilingualType.HE); } public void BindFontID() { if (FontBan) return; if (FontID != 0) return; var text = GetComponent(); if (!text) return; FontID = MultilingualManager.Instance.GetFontGroupID(text.font); } public MultiTextConfig GetMultiTextConfig(MultilingualType type) { foreach (var cfg in TextCfg) { if (cfg.Type != type) continue; return cfg; } return null; } private void MatchTextCfg(TextMeshProUGUI text, MultilingualType type) { // 仅 5 主语言(ZH/TDZH/EN/JP/KR)使用各自的样式键; // 其他所有语言(RU/FR/DE/AR/泰语/Custom 等)一律转成 EN 来查询样式, // 避免每个语言单独配同一份方案。 MultilingualType lookupType = IsPrimaryLanguageCfg(type) ? type : MultilingualType.EN; // 第 1 级:prefab 上的 TextCfg(局部 override) // 只接受 lookupType 精确命中;不回退到 TextCfg 里的 EN(避免"配了 EN 就吃掉所有非 EN 语言") // 命中后用 ExcuteConfigForce 强写 5 个字段,无视 ApplyXxx 开关 // 语义:在 prefab 上手动配 override 就是要全字段生效 foreach (var cfg in TextCfg) { if (cfg.Type != lookupType) continue; cfg.ExcuteConfigForce(text); return; } // 第 2 级:全局 TextStylePresetDataAssets(按 Preset + lookupType 查表) // preset 走 ExcuteConfig(看 ApplyXxx 开关),未勾选的字段保留 prefab 原值 // None 也是一种 Preset:作为"默认通用方案"参与查表,所有 TMP 默认就是 None,让全局规则不需要每个 TMP 单独标 { var presetData = Table.Instance?.TextStylePresetDataAssets; var picked = presetData?.GetConfig(Preset, lookupType); picked?.ExcuteConfig(text); } // 第 3 级:都没找到 → 不动 TMP(保持 prefab 上的字号/行距原值) } // 5 主语言才走自己的 TextCfg;其他全部走 EN private static bool IsPrimaryLanguageCfg(MultilingualType type) { return type == MultilingualType.ZH || type == MultilingualType.TDZH || type == MultilingualType.EN || type == MultilingualType.JP || type == MultilingualType.KR; } public void SetMultilingualText(string str, MultilingualType type, TMP_FontAsset font) { var text = GetComponent(); if (!text) return; text.text = str; ApplyDefaultEmbeddedColor(text); if (font != null) text.font = font; MatchTextCfg(text, type); ApplyRTLDirection(text, type); } private static void ApplyDefaultEmbeddedColor(TextMeshProUGUI text) { var colorTag = $""; text.text = text.text.Replace("", colorTag); text.text = text.text.Replace("", colorTag); text.text = text.text.Replace("**<", colorTag); text.text = text.text.Replace(">**", ""); } } }