语义映射

CLIFF 的 clan 表达「这段文本是什么语义家族」(界面标签、提示、专有名词、对话……),UE 的 NamespaceFTextId 的第一段。两者不是一回事,插件用三张可配置的映射表把它们接起来,绝不硬编码。

IMPORTANT

注意术语消歧:CLIFF 的 namespace(canonical ID 的第一段,插件中等于 CLIFF Namespace 设置)与 UE 的 FTextKey Namespace 是两个不同概念。本文凡写 UE Namespace 都指后者。CLIFF namespace 不进入 UE Namespace

三张映射表

设置项方向用途
Clan to Namespaceclan → UE Namespace导入时决定写进哪个 Namespace;导出时反向查找 clan
Namespace to TypeUE Namespace → CLIFF type导出时推导 type
Namespace to EmotionUE Namespace → CLIFF emotion导出时推导默认 emotion

位置:编辑 > 项目设置 > 插件 > CLIFF Localization Suite > Semantic Mapping

默认值

FCliffSemanticMapping::CreateDefault() 提供的内置表。生效映射 = 内置默认表 + 项目设置中的条目(同键时项目设置覆盖默认值):

Clan to Namespace

clanUE Namespace
categoryUObjectCategory
tooltipUObjectToolTips
short-tooltipUObjectShortTooltips
display-nameUObjectDisplayNames
proper-nounUObjectDisplayNames
dialogueDialogue

Namespace to Type

UE Namespacetype
UObjectCategorylabel
UObjectToolTipsprompt
UObjectShortTooltipsprompt
UObjectDisplayNamesproper-noun
Dialoguedialogue

Namespace to Emotion

UE Namespaceemotion
Dialogueneutral

NOTE

display-nameproper-noun 都映射到 UObjectDisplayNames:前者是「类/字段显示名」这个来源,后者是「它按语义是专有名词」这个结论。反向查找时先命中者优先,因此导出的 clan 通常是表里的第一项。若你的项目需要更精确的命名,把不需要的条目删掉即可。

导入方向:clan → UE Namespace

FCliffSemanticMapping::ResolveNamespace(clan) 的实际行为(导入器 CliffImporter.cpp):

  1. ClanToNamespace 中命中 → 用该 UE Namespace(视为「显式」映射)
  2. 未命中 → 回退为 CLIFF header 的 namespace(即项目标识本身,如 p-cliff-l10n-suite),并记录 warning:CLIFF clan '…' has no semantic mapping; using CLIFF namespace '…' as UE namespace.

因此一个只写 clan: ui 而没有配置映射的项目仍然能导入,只是所有条目会落到以 CLIFF namespace 命名的 UE Namespace 下。若你希望它落到项目自己的 UI 命名空间(例如 MyGameUI),加一条映射即可:

; Config/DefaultEditor.ini(也可以直接在项目设置面板里编辑)
[/Script/CliffLocalizationSuite.CliffLocalizationSuiteSettings]
+ClanToNamespace=(("ui", "MyGameUI"))

导出方向:UE Namespace → clan / type / emotion

clanResolveClanFromNamespace):

  1. ClanToNamespace 反查(精确匹配值)→ 返回对应 clan
  2. 未命中 → kebab-slug 化 UE Namespace:驼峰拆词 + 转小写 + 非 [a-z0-9-] 字符替换为 - + 合并/裁剪连字符(UObjectDisplayNamesu-object-display-names
  3. slug 为空 → 用 ue
  4. 未命中会记录 warning,提示你补映射表

typeResolveTypeForNamespace):命中 NamespaceToType 则用之,否则返回空,由导出器落到 sentence + warning。

emotionResolveEmotionForNamespace):命中 NamespaceToEmotion 则用之;否则 emotion 字段不写,交给 CLIFF 的默认规则(dialogue / monologue / idiom[neutral],其余 → [objective])。

UE 侧实际能拿到什么

UE 文本来源UE Namespace能推导出的语义
C++ LOCTEXT#define LOCTEXT_NAMESPACE,通常是模块名无法单凭 Namespace 区分 label / dialogue → 默认 sentence
C++ NSLOCTEXT显式参数同上
资产 / 蓝图 FText资产内 namespace(包本地化 namespace 会被剥离)站点描述形如 "{StructPath} [Script Bytecode]",语义需靠规则表
类 / 字段 DisplayName固定 UObjectDisplayNamesproper-noun
类 / 字段 Tooltip固定 UObjectToolTips / UObjectShortTooltipsprompt
UObject Category 元数据固定 UObjectCategory(由 GatherTextFromMetadata 产出)label
DialogueWave固定 Dialoguedialogue

TIP

想把项目自己的 UI 文本也映射成 label,最省事的做法是给这类文本的 Namespace 加规则。例如源码里统一使用 #define LOCTEXT_NAMESPACE "MyGameUI",然后:

Clan to Namespace:   ui        → MyGameUI
Namespace to Type:   MyGameUI  → label

导出时 MyGameUI 的条目就会写成 clan: ui + type: label,导入时又原路回到 MyGameUI

降级与告警口径

情况结果
clan 无显式映射UE Namespace = CLIFF header 的 namespace(可正常往返,但建议补映射)
UE Namespace 无反向映射clan = kebab-slug + warning
type 无法推导type: sentence + warning
emotion 无法推导不写该字段(CLIFF 默认规则生效)
元数据存在元数据优先于所有映射表(上一轮导入写入的语义不会被映射表覆盖)

NOTE

因元数据优先级最高,调整映射表只会影响「从未经过 CLIFF 往返」的既有 UE 数据;已经导入过一次的条目会稳定保留其语义,不会因为改表而漂移。