32 KiB
TH1 多语言系统 (Multilingual System) 技术文档
目录
系统概述
TH1 多语言系统是一套基于 Unity ScriptableObject 的本地化解决方案,覆盖文本翻译、字体切换、排版适配三大核心功能。系统以中文 (ZH) 为基准语言,通过编辑器工具自动从场景/Prefab/ScriptableObject 中提取中文文本并分配唯一 ID,然后导出 Excel 供翻译团队填写,翻译完成后再导回 Unity Asset。运行时根据当前语言类型,使用 ID 查找对应翻译文本,并自动切换字体和排版参数。
支持语言
定义在 MultilingualType 枚举中:
| 枚举值 | 语言 | 说明 |
|---|---|---|
None |
无 | 默认/未设置 |
ZH |
简体中文 | 基准语言 |
TDZH |
繁体中文 | |
EN |
英语 | 默认 fallback 语言 |
JP |
日语 | |
KR |
韩语 | |
RU |
俄语 | |
ES |
西班牙语 | |
PT |
葡萄牙语 | |
FR |
法语 | |
Max |
最大值 | 哨兵值,用于遍历 |
核心架构
┌─────────────────────────────────────────────────────────────┐
│ Editor (编辑器) │
│ MultilingualEditorWindow │
│ ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌────────────┐ │
│ │ 文本提取 │ │ Excel导出 │ │ Excel导回 │ │ 字符集管理 │ │
│ └─────┬────┘ └─────┬────┘ └─────┬─────┘ └─────┬──────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ MultilingualData (ScriptableObject) │ │
│ │ Assets/Resources/Export/Multilingual.asset │ │
│ └───────────────────────┬─────────────────────────────────┘ │
└──────────────────────────┼───────────────────────────────────┘
│
┌──────────────────────────┼───────────────────────────────────┐
│ Runtime (运行时) │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ MultilingualManager (单例) │ │
│ │ - 语言切换 │ │
│ │ - 文本查询 (ID → 翻译文本) │ │
│ │ - 字体查询 (FontID → 对应字体) │ │
│ └───────────────────┬─────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ MultilingualTextMono (MonoBehaviour) │ │
│ │ - 挂载在每个需要翻译的 TextMeshProUGUI │ │
│ │ - 持有 ID, FontID, TextCfg │ │
│ │ - 响应语言切换事件 │ │
│ └───────────────────┬─────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ MultiTextConfig (排版配置) │ │
│ │ - 每语言独立的 FontSize / Spacing 等 │ │
│ └─────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
数据层
MultilingualData (MultilingualData.cs)
核心 ScriptableObject,存储路径:Assets/Resources/Export/Multilingual.asset
主要字段
| 字段 | 类型 | 说明 |
|---|---|---|
Items |
List<MultilingualItem> |
所有多语言文本条目 |
FontGroups |
List<MultilingualFontGroup> |
字体组列表 |
TargetTypes |
List<MultilingualType> |
系统语言 → 游戏语言的映射表 |
ItemDict |
Dictionary<uint, MultilingualItem> |
ID → Item 的运行时字典缓存 |
核心方法
| 方法 | 说明 |
|---|---|
GetMultilingualStr(id, type) |
运行时文本查询,会解析嵌套引用并添加颜色标签 |
GetMultilingualStrEditor(id, type) |
编辑器文本查询,解析嵌套引用但保留 **<>** 格式 |
GetMultilingualFont(fontId, type) |
根据字体组ID和语言类型获取对应 TMP_FontAsset |
GetFontGroupID(font) |
根据中文字体反查字体组ID |
RefreshDict() |
重建 ID → Item 字典缓存 |
ResolveEmbeddedStringsRunning(str, type) |
运行时解析:**<id>** → <color=#hex>翻译文本</color> |
ResolveEmbeddedStrings(str, type) |
编辑器解析:**<id>** → **<翻译文本>** |
UnResolveEmbeddedStrings(str, type) |
反向解析:**<翻译文本>** → **<id>** |
AlignEmbeddedStringsToZH(zhResolved, otherOrigin, type, itemId) |
将其他语言的嵌套引用对齐到中文的 ID 格式 |
GetSystemLanguageTargetMultilingual(type) |
通过 TargetTypes 映射系统语言到游戏语言 |
MultilingualItem
单条多语言文本数据:
| 字段 | 类型 | 说明 |
|---|---|---|
ID |
uint |
唯一标识符 |
ZH |
string |
简体中文文本(基准) |
TDZH / EN / JP / KR / RU / ES / PT / FR |
string |
各语言翻译 |
IsProperNoun |
bool |
是否为专有名词 |
IsDialogue |
bool |
是否为对话文本 |
DialogueSpeaker |
string |
对话说话人 |
IsDeprecated |
bool |
是否已废弃 |
IsCustom |
bool |
是否为自定义条目(不被自动覆盖) |
IsSpecialTerm |
bool |
是否为专有名词(嵌套引用的子串) |
Color |
string |
专有名词高亮颜色(默认橘色) |
Icon |
string |
专有名词前缀图标 sprite 名称 |
Desc |
string |
描述信息(来源路径),非序列化 |
核心方法
GetStrByType(type)— 根据语言类型返回对应翻译字符串IsTranslate(type)— 检查指定语言是否已翻译(非空即视为已翻译)Refresh()— 统一换行符为\n
MultilingualFontGroup
字体组,为每种语言指定不同的 TMP_FontAsset:
| 字段 | 类型 | 说明 |
|---|---|---|
FontID |
uint |
字体组唯一ID |
ZHFont / TDZHFont / ENFont / JPFont / KRFont / RUFont / ESFont / PTFont / FRFont |
TMP_FontAsset |
各语言对应字体 |
MultilingualFieldAttribute (MultilingualFieldAttribute.cs)
自定义 Attribute,标记 ScriptableObject 中需要参与多语言导出的字段。
// 用法示例
[MultilingualField]
public string NormalText;
[MultilingualField(isProperNoun: true, isDialogue: true)]
public string CharacterName;
[MultilingualField(true, true, false)]
public string DialogueText;
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
IsProperNoun |
bool |
false |
标记为专有名词 |
IsDialogue |
bool |
false |
标记为对话文本 |
IsDeprecated |
bool |
false |
标记为已废弃 |
运行时层
MultilingualManager (MultilingualManager.cs)
全局单例管理器,是运行时多语言功能的统一入口。
初始化流程
Init()
├─ RefreshMultilingualData() // 加载 Resources/Export/Multilingual.asset
├─ 读取 ConfigManager 中保存的语言设置
├─ 若为 None → GetSystemLanguage() 自动检测系统语言
└─ ChangedMultilingual(type) // 应用语言切换
核心 API
| 方法 | 说明 |
|---|---|
GetMultilingualText(uint id) |
根据 ID 获取当前语言的翻译文本 |
GetMultilingualText(string str) |
字符串ID版本(解析后调用uint版本) |
GetMultilingualTextSafe(string idString) |
安全版本,解析失败返回原始字符串 |
GetMultilingualFont(uint fontId) |
获取当前语言对应的字体 |
ChangedMultilingual(type) |
切换语言:刷新所有 MultilingualTextMono 组件 |
SetUIText(textCom, id, paramList) |
动态设置 UI 文本的多语言 ID 和参数 |
SetUIText(textCom, paramList) |
仅更新参数(保持现有 ID) |
GetSystemLanguage() |
检测操作系统语言并映射到游戏语言 |
GetLanguageByString(str) |
根据字符串内容的 Unicode 范围推断语言类型 |
系统语言检测映射
| 系统语言 | 映射到 |
|---|---|
| Chinese / ChineseSimplified | ZH |
| ChineseTraditional | TDZH |
| Japanese | JP |
| Korean | KR |
| Russian | RU |
| Spanish | ES |
| Portuguese | PT |
| French | FR |
| 其他所有语言 | EN(默认) |
检测到系统语言后,还会经过
TargetTypes映射表做一次重定向,允许配置"某系统语言使用另一种游戏语言"的场景。
语言切换完整流程
ChangedMultilingual(type)
├─ RefreshMultilingualData() // 确保数据已加载
├─ RefreshTextComs() // 遍历 UICanvas 下所有 MultilingualTextMono
├─ _currentType = type // 更新当前语言
├─ foreach textCom → OnMultilingualChanged() // 通知每个文本组件刷新
└─ ConfigManager 保存语言设置 // 持久化
组件层
MultilingualTextMono (MultilingualTextMono.cs)
挂载在每个需要本地化的 TextMeshProUGUI 游戏对象上的 MonoBehaviour 组件。
关键字段
| 字段 | 类型 | 说明 |
|---|---|---|
ID |
uint |
对应 MultilingualItem.ID,0 表示未设置 |
FontID |
uint |
对应字体组ID,0 表示未设置 |
Ban |
bool |
禁止文本替换(仅做字体切换) |
NoExport |
bool |
导出 Excel 时跳过此组件 |
FontBan |
bool |
禁止字体切换 |
TextCfg |
List<MultiTextConfig> |
各语言排版配置列表 |
ParamList |
List<string> |
运行时参数列表,替换文本中的 {param} 占位符 |
PreviewType |
MultilingualType |
编辑器预览语言类型 |
刷新逻辑 OnMultilingualChanged()
OnMultilingualChanged()
│
├─ [字体处理] (FontBan = false 时)
│ ├─ BindFontID() // 自动绑定字体组ID
│ ├─ GetMultilingualFont(FontID) // 获取当前语言字体
│ ├─ text.font = font // 应用字体
│ └─ MatchTextCfg(text, type) // 应用排版配置
│
└─ [文本处理] (Ban = false 时)
├─ GetMultilingualText(ID) // 获取翻译文本
├─ Regex.Replace("{param}") // 按顺序替换 {param} 占位符
└─ 临时颜色替换处理 // TODO: 将 **<>** 转为 <color>
参数化文本机制
文本中可使用 {param} 占位符,运行时通过 ParamList 按顺序替换:
// 多语言文本: "你获得了 {param} 个 {param}"
// ParamList: ["10", "金币"]
// 结果: "你获得了 10 个 金币"
MultiTextConfig (MultiTextConfig.cs)
针对不同语言的 TextMeshPro 排版配置,因为不同语言的字体大小、间距需求不同。
| 字段 | 说明 |
|---|---|
Type |
语言类型 |
FontSize |
字体大小 |
CharacterSpacing |
字符间距 |
WordSpacing |
单词间距 |
LineSpacing |
行间距 |
ParagraphSpacing |
段落间距 |
构造时从当前 TextMeshProUGUI 组件快照排版参数,切换语言时通过 ExcuteConfig() 应用。
编辑器工具层
MultilingualEditorWindow (MultilingualEditorWindow.cs)
Unity 编辑器窗口,通过菜单 Tools → 多语言编辑器 打开。是多语言工作流的核心编辑器工具。
功能面板布局
┌─────────────────────────────────────────────────┐
│ [保存] [清空] [导出 Excel] [Excel 导回] │
│ [生成基础配置(中文字体)] [清除预览] │
├─────────────────────────────────────────────────┤
│ [添加字体组] │
│ □ 是否批量替换 <color=***> │
├─────────────────────────────────────────────────┤
│ [语言选择下拉框] │
│ [检查字符集是否有新增] [TXT并集] [创建新字符集TXT] │
├─────────────────────────────────────────────────┤
│ 筛选区域(红色框) │
│ □ 筛选活跃文本 □ 筛选专有名词 │
│ □ 筛选对话文本 □ 筛选已废弃文本 │
│ □ 筛选英文未翻译 □ 筛选繁中未翻译 │
│ □ 筛选日文未翻译 □ 筛选韩文未翻译 │
│ □ 筛选俄语未翻译 □ 筛选西班牙语未翻译 │
│ □ 筛选葡萄牙语未翻译 □ 筛选法语未翻译 │
│ □ 筛选任意未翻译 □ 筛选专有名词 │
│ [导出 Excel 筛选类型文本] │
├─────────────────────────────────────────────────┤
│ 系统语言映射配置(白色框) │
│ 系统语言ZH 对应游戏语言:[下拉框] │
│ 系统语言TDZH 对应游戏语言:[下拉框] │
│ ... │
├─────────────────────────────────────────────────┤
│ 字体组列表 │
│ ┌──────────────────────────────────────────┐ │
│ │ ID: 1 [x] │ │
│ │ ZH: [SourceHanSansCN-Bold SDF] │ │
│ │ TDZH: [...] │ │
│ │ EN: [...] JP: [...] KR: [...] │ │
│ │ RU: [...] ES: [...] PT: [...] │ │
│ │ FR: [...] │ │
│ └──────────────────────────────────────────┘ │
├─────────────────────────────────────────────────┤
│ 多语言条目列表(分页显示,每页10条) │
│ [上一页] [下一页] │
│ ┌──────────────────────────────────────────┐ │
│ │ 1: │ │
│ │ 中文:你好世界 │ │
│ │ 英语:Hello World │ │
│ │ Unicode:4F60 597D 4E16 754C │ │
│ └──────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
核心功能详解
1. 导出 Excel (AssetExportToExcel)
完整流程:
AssetExportToExcel(isFilter)
│
├─ DuplicateRemoval() // 去重 & 排序
│ ├─ 按 ID 排序 Items
│ ├─ 可选:批量 TransformString() // <color=yellow>X</color> → **<X>**
│ └─ 以 ZH 文本为 key 去重
│
├─ 扫描场景 UICanvas
│ ├─ 遍历所有 TextMeshProUGUI
│ ├─ 过滤含中文/英文的文本
│ ├─ 自动添加 MultilingualTextMono 组件
│ ├─ ExportSpecialTerm() 处理 **<>** 嵌套
│ ├─ 分配 ID(已存在的复用,新文本递增)
│ └─ 记录活跃状态 & 描述路径
│
├─ 扫描 Prefab (Assets/Resources/Prefab/)
│ └─ 同上逻辑
│
├─ 扫描 ScriptableObject (Assets/Resources/DataAssets/)
│ ├─ TraverseObject() 反射遍历
│ ├─ 识别 [MultilingualField] 标记的字段
│ ├─ 提取 string / List<string> 类型字段
│ ├─ 分配 ID 并替换原文本为 ID 字符串
│ └─ 导出副本到 Assets/Resources/Export/
│
├─ 生成 TXT 中间文件 (../Tools/MultilingualTxt.txt)
│ ├─ 分隔符:行间 "!@#$%",列间 "%$#@!"
│ └─ 列顺序:ID | Active | ZH | TDZH | EN | JP | KR | RU | ES | PT | FR
│ | IsProperNoun | IsDialogue | Speaker | IsDeprecated
│ | IsCustom | IsSpecialTerm | Color | Icon | Desc
│
└─ WriteToExcel() // 调用 Python 脚本
└─ python ../Tools/ExportStringToExcel.py
2. Excel 导回 (ExcelExportToAsset)
ExcelExportToAsset()
│
├─ GetExcelData() // 调用 Python 脚本读取 Excel
│ └─ python ../Tools/PrintExcelString.py
│ → 输出到 ../Tools/MultilingualTxt.txt
│
├─ 解析 TXT 文件
│ ├─ 按 "!@#$%" 分行
│ ├─ 按 "%$#@!" 分列
│ └─ 更新/新增 MultilingualItem
│
├─ 嵌套引用对齐
│ ├─ UnResolveEmbeddedStrings(ZH) // 中文:**<文本>** → **<id>**
│ └─ AlignEmbeddedStringsToZH(...) // 其他语言:对齐中文ID格式
│
└─ 保存 Asset
3. 生成基础配置
为场景中和 Prefab 中所有 MultilingualTextMono 组件:
- 自动生成中文 (ZH) 的
MultiTextConfig(快照当前排版参数) - 自动绑定
FontID(根据当前使用的中文字体匹配字体组)
4. 清除预览
将所有 MultilingualTextMono 组件的文本和字体恢复为中文状态。
5. 筛选与过滤导出
支持多种筛选条件组合导出:
- 活跃文本 — 当前场景/Prefab/Asset 中实际在使用的文本
- 专有名词 / 对话文本 / 已废弃
- 各语言未翻译 — 对应语言字段为空
- 任意未翻译 — 任何一种语言为空
- 专有名词(Special Term) — 嵌套引用的子串
专有名词嵌套引用机制
这是系统中最复杂的特性,用于处理"文本中嵌入其他可翻译文本"的场景。
语法格式
**<文本内容>** // 基础格式
**<![n]文本内容>** // 带前缀n的格式(n为数字,用于多个嵌套时区分顺序)
转换流程
导出时 (中文 → ID)
原始文本: "获得了 **<火焰剑>** 和 **<冰霜盾>**"
↓ ExportSpecialTerm()
↓ "火焰剑" → 分配 ID=42, "冰霜盾" → 分配 ID=43
导出后: "获得了 **<42>** 和 **<43>**"
火焰剑(ID=42) 和 冰霜盾(ID=43) 作为独立的 MultilingualItem 存储,标记 IsSpecialTerm = true。
导回时 (其他语言对齐)
中文已转换: "获得了 **<42>** 和 **<43>**"
英文原始: "Got **<Flame Sword>** and **<Frost Shield>**"
↓ AlignEmbeddedStringsToZH()
英文对齐后: "Got **<42>** and **<43>**"
对齐规则:
- 带前缀
![n]— 按 n 值匹配中文对应的**<![n]id>** - 无前缀 — 按出现顺序依次对齐
运行时解析
存储格式: "获得了 **<42>** 和 **<43>**"
↓ ResolveEmbeddedStringsRunning()
↓ ID=42 查到 ZH="火焰剑", Color="#FF6600", Icon="sword"
运行时文本: "获得了 <sprite name="sword"><color=#FF6600>火焰剑</color> 和 <color=#FF6600>冰霜盾</color>"
运行时解析特性:
- 自动添加
<color=hex>颜色标签(默认橘色rgb(255, 165, 0)) - 支持
<sprite>图标前缀 - 检测并拒绝嵌套引用(防止递归)
编辑器解析
编辑器中 (ResolveEmbeddedStrings) 将 **<id>** 还原为 **<翻译文本>** 格式,便于在 Excel 中阅读。
字体管理系统
字体组 (FontGroup)
每个字体组包含同一设计风格在不同语言下的字体映射:
FontGroup (ID=1)
├─ ZH: SourceHanSansCN-Bold
├─ TDZH: (对应繁中字体)
├─ EN: (对应英文字体)
├─ JP: (对应日文字体)
└─ ...
字体切换流程
语言切换
→ MultilingualTextMono.OnMultilingualChanged()
→ BindFontID() // 如果 FontID==0,从当前中文字体推断
→ GetMultilingualFont(FontID) // 用字体组ID + 当前语言获取字体
→ text.font = font // 应用字体
→ MatchTextCfg(text, type) // 应用排版配置
排版配置 (MultiTextConfig)
不同语言因字体差异可能需要不同的排版参数。每个 MultilingualTextMono 可以为每种语言配置独立的:
- 字体大小 (
FontSize) - 字符间距 (
CharacterSpacing) - 单词间距 (
WordSpacing) - 行间距 (
LineSpacing) - 段落间距 (
ParagraphSpacing)
Excel 导入导出流程
中间文件格式
路径:../Tools/MultilingualTxt.txt(相对于 Unity 项目目录)
{ID}%$#@!{Active}%$#@!{ZH}%$#@!{TDZH}%$#@!{EN}%$#@!{JP}%$#@!{KR}%$#@!{RU}%$#@!{ES}%$#@!{PT}%$#@!{FR}%$#@!{IsProperNoun}%$#@!{IsDialogue}%$#@!{Speaker}%$#@!{IsDeprecated}%$#@!{IsCustom}%$#@!{IsSpecialTerm}%$#@!{Color}%$#@!{Icon}%$#@!{Desc}!@#$%
- 行分隔符:
!@#$% - 列分隔符:
%$#@!
外部 Python 脚本
| 脚本 | 路径 | 功能 |
|---|---|---|
ExportStringToExcel.py |
../Tools/ |
读取 TXT → 写入 Excel |
PrintExcelString.py |
../Tools/ |
读取 Excel → 写入 TXT |
完整工作流
┌──────────────┐
│ Unity Editor │
└──────┬───────┘
│ "导出 Excel"
▼
┌─────────────────────────────┐
│ 1. 扫描场景/Prefab/Asset │
│ 2. 提取中文 → 分配ID │
│ 3. 生成 MultilingualTxt.txt │
└──────────────┬──────────────┘
│
▼
┌─────────────────────────────┐
│ ExportStringToExcel.py │
│ TXT → Excel │
└──────────────┬──────────────┘
│
▼
┌─────────────────────────────┐
│ 翻译团队在 Excel 中填写翻译 │
└──────────────┬──────────────┘
│
▼
┌─────────────────────────────┐
│ PrintExcelString.py │
│ Excel → TXT │
└──────────────┬──────────────┘
│
▼
┌─────────────────────────────┐
│ "Excel 导回" │
│ 1. 解析 TXT │
│ 2. 更新 MultilingualItem │
│ 3. 对齐嵌套引用 │
│ 4. 保存 Multilingual.asset │
└─────────────────────────────┘
字符集管理
用于 TextMeshPro 字体 Atlas 生成,确保字体包含游戏中使用的所有字符。
功能
- 检查字符集是否有新增 — 对比现有
{Type}CharSet.txt与当前多语言数据 - 创建新字符集 TXT — 生成包含所有必要字符的 TXT 文件
字符集生成流程
OnBuildTxt(type)
├─ 加载已有并集 TXT(可选) // 用户指定的基础字符集
├─ AddBasicCharacters() // 添加 A-Z, a-z, 0-9, 常用标点
├─ ExtractFromI2Languages() // 从 Multilingual.asset 提取指定语言的所有字符
└─ ExportCharacterList() // 导出到 Assets/Fonts/{Type}CharSet.txt
基础字符集
自动包含:
- 大写字母 A-Z
- 小写字母 a-z
- 数字 0-9
- 常用标点符号(包含中英文标点)
文件清单
运行时代码
| 文件 | 路径 | 职责 |
|---|---|---|
MultilingualData.cs |
TH1_Logic/Multilingual/ |
数据容器 + 嵌套引用解析 |
MultilingualManager.cs |
TH1_Logic/Multilingual/ |
运行时管理器单例 |
MultilingualTextMono.cs |
TH1_Logic/Multilingual/ |
UI 文本组件 |
MultiTextConfig.cs |
TH1_Logic/Multilingual/ |
排版参数配置 |
MultilingualFieldAttribute.cs |
TH1_Logic/Multilingual/ |
字段标记 Attribute |
编辑器代码
| 文件 | 路径 | 职责 |
|---|---|---|
MultilingualEditorWindow.cs |
TH1_Logic/Editor/ |
编辑器窗口,导入导出工具 |
资源文件
| 文件 | 路径 | 说明 |
|---|---|---|
Multilingual.asset |
Assets/Resources/Export/ |
多语言数据 ScriptableObject |
{Type}CharSet.txt |
Assets/Fonts/ |
各语言字符集 |
MultilingualTxt.txt |
../Tools/ |
导入导出中间文件 |
ExportStringToExcel.py |
../Tools/ |
导出 Python 脚本 |
PrintExcelString.py |
../Tools/ |
导入 Python 脚本 |
数据流总览
┌────────────────────────────────────────────────────────────────────┐
│ 数据源 │
│ │
│ Scene (UICanvas) Prefabs ScriptableObjects │
│ └─ TextMeshProUGUI └─ TextMeshPro └─ [MultilingualField] │
│ + MultilingualTextMono 标记的 string 字段 │
└──────────────┬───────────────┬──────────────────┬──────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────┐
│ MultilingualEditorWindow │
│ "导出 Excel" 按钮 │
└──────────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Multilingual.asset │
│ ┌─────────────────────────────────────┐ │
│ │ Item[0]: ID=1, ZH="开始游戏" │ │
│ │ Item[1]: ID=2, ZH="设置" │ │
│ │ Item[2]: ID=3, ZH="退出" │ │
│ │ ... │ │
│ └─────────────────────────────────────┘ │
│ ┌─────────────────────────────────────┐ │
│ │ FontGroup[0]: ID=1 │ │
│ │ ZH=Bold, EN=Arial, JP=NotoSans... │ │
│ └─────────────────────────────────────┘ │
└──────────────────────┬──────────────────────┘
│
┌───────────┴───────────┐
▼ ▼
┌──────────────────┐ ┌──────────────────────┐
│ MultilingualTxt │ │ Runtime │
│ .txt │ │ MultilingualManager │
│ ↕ Python ↕ │ │ │ │
│ Excel 文件 │ │ ▼ │
│ (翻译团队) │ │ MultilingualTextMono │
└──────────────────┘ │ │ │
│ ▼ │
│ TextMeshProUGUI │
│ (最终显示) │
└──────────────────────┘
附录:TransformString 批量替换
编辑器提供的批量字符串转换功能,将旧版 <color=yellow> 标记转为新版 **<>** 专有名词格式:
输入: "<color=yellow>火焰剑</color>"
输出: "**<火焰剑>**"
匹配规则:<color=yellow>内容</color> 或 <color=#FFFF00>内容</color>
此功能通过编辑器中的 "是否批量替换 <color=***>" 开关控制,仅在导出 Excel 时生效。