FName、FString和FText
FName
核心特点
- 不可变且唯一:
FName
存储的字符串是大小写不敏感的,内容不可修改,内部通过哈希表管理唯一实例,相同字符串共享同一内存。 - 高效查询:基于哈希值的快速比较,适合频繁的查找、匹配操作。
- 轻量级:仅存储字符串的哈希值和索引,内存占用低。
典型用途
- 资源标识(如材质、纹理的名称)。
- 游戏对象的标签(
Actor
的Tag
)、骨骼名称、属性名(UPROPERTY
名称)。 - 避免用于需要动态生成或本地化的文本。
示例代码
FName TextureName = TEXT("MainTexture");
if (TextureName == FName(TEXT("maintexture"))) // 不区分大小写,结果为true
{
// ...
}
转换
FNames 只能被转换为 FStrings 和 FText,只能从 FStrings 进行转换
FString Str = TEXT("DynamicString");
FName Name = FName(*Str); // FString -> FName 不可靠。因为 FName 不区分大小写,所以转换存在损耗。
// FText 不能直接转换成 FName。它需要先转换成 FString,然后再转成 FName。
FString
核心特点
- 动态可变:类似
std::string
,支持拼接、替换、格式化等操作。 - 性能开销较高:频繁修改时可能引发内存重新分配。
- 大小写敏感:直接存储原始字符串内容。
典型用途
- 动态构建字符串(如文件路径拼接、网络数据解析)。
- 调试输出(
UE_LOG
)、处理用户输入。 - 需要复杂字符串操作的场景。
示例代码
FString Path = FPaths::ProjectDir();
Path.Append(TEXT("Content/Asset.txt"));
FString Message = FString::Printf(TEXT("Health: %d"), 100);
转换
FText Text = LOCTEXT("Key", "Hello");
FString Str1 = Text.ToString(); // FText -> FString 不可靠,因为这种转换对于某些语言来说可能存在损耗。
FName Name = TEXT("StaticName");
FString Str2 = Name.ToString(); // FName -> FString 可靠
FText
核心特点
- 本地化支持:自动根据当前语言环境切换显示内容,需配合本地化工具(如
LOCTEXT
宏)使用。 - 不可变但可格式化:内容不可直接修改,但可通过参数化生成新文本。
- 显示友好:处理文本换行、日期/货币格式等国际化内容。
典型用途
- 用户界面(UI)文本、游戏内对话。
- 需要多语言支持的文本(如中文、英文切换)。
- 格式化字符串(如“玩家名: {0}”、“得分: {1}”)。
示例代码
// 在代码中定义本地化键
FText WelcomeMessage = NSLOCTEXT("GameNamespace", "Welcome", "Hello, Player!");
// 格式化文本
FText FormattedText = FText::Format(LOCTEXT("ScoreFormat", "Score: {0}"), 100);
转换
FString Str = TEXT("DynamicString");
FText Text1 = FText::FromString(Str); // FString -> FText 在一些情况下有效,但需注意 FString 内容不会从 FText 的"自动本地化"中受益。
FName Name = TEXT("StaticName");
FText Text2 = FText::FromName(Name); // FName -> FText 在一些情况下有效,但需注意 — FNames 内容不会从 FText 的"自动本地化"中受益。
三者的关键区别
特性 | FName | FString | FText |
---|---|---|---|
可变性 | 不可变 | 可变 | 不可变(但可格式化) |
内存管理 | 全局唯一,共享实例 | 独立存储,动态分配 | 可能存储多语言数据 |
性能 | 哈希查询极快 | 动态操作可能较慢 | 本地化处理高效 |
大小写敏感 | 不敏感 | 敏感 | 敏感 |
本地化支持 | 不支持 | 不支持 | 支持 |
典型用例 | 资源名、标签、属性名 | 文件操作、动态字符串构建 | UI文本、多语言、格式化文本 |
注意事项
- FName
- 避免存储动态内容(如玩家输入的名称),因其内容不可变。
- 大小写转换可能导致哈希冲突(如
FName(TEXT("NAME"))
和FName(TEXT("name"))
视为相同)。 - 虽然本身不区分大小写,但转换类型后还是区分的(
FName(TEXT("NAME")).ToString()
和FName(TEXT("name")).ToString()
并不相等)
- FString
- 频繁拼接操作建议使用
FString::Reserve()
预分配内存。 - 避免在性能关键代码中过度使用(如每帧执行的逻辑)。
- FString 虽然大小写敏感,但使用 == 比较时是不区分大小写的
- 频繁拼接操作建议使用
- FText
- 必须通过本地化工具(如
Localization Dashboard
)管理多语言文本。 - 直接使用字符串字面量时,优先用
LOCTEXT
而非FText::FromString
,以支持本地化。
- 必须通过本地化工具(如