176 lines
6.6 KiB
C#
176 lines
6.6 KiB
C#
/*
|
||
* @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<MultiTextConfig> TextCfg = new List<MultiTextConfig>();
|
||
private List<string> _paramList;
|
||
|
||
public MultilingualType PreviewType
|
||
{
|
||
get => _previewType;
|
||
set => _previewType = value;
|
||
}
|
||
private MultilingualType _previewType = MultilingualType.ZH;
|
||
|
||
public List<string> ParamList
|
||
{
|
||
get => _paramList ??= new List<string>();
|
||
set => _paramList = value;
|
||
}
|
||
|
||
private void OnEnable()
|
||
{
|
||
OnMultilingualChanged();
|
||
}
|
||
|
||
public void OnMultilingualChanged()
|
||
{
|
||
var text = GetComponent<TextMeshProUGUI>();
|
||
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<TextMeshProUGUI>();
|
||
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<TextMeshProUGUI>();
|
||
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 = $"<color={MultilingualRichTextColors.DefaultEmbeddedHex}>";
|
||
text.text = text.text.Replace("<color=yellow>", colorTag);
|
||
text.text = text.text.Replace("<color=orange>", colorTag);
|
||
text.text = text.text.Replace("**<", colorTag);
|
||
text.text = text.text.Replace(">**", "</color>");
|
||
}
|
||
}
|
||
}
|