FName、FString和FText

FName

核心特点

  • 不可变且唯一FName存储的字符串是大小写不敏感的,内容不可修改,内部通过哈希表管理唯一实例,相同字符串共享同一内存。
  • 高效查询:基于哈希值的快速比较,适合频繁的查找、匹配操作。
  • 轻量级:仅存储字符串的哈希值和索引,内存占用低。

典型用途

  • 资源标识(如材质、纹理的名称)。
  • 游戏对象的标签(ActorTag)、骨骼名称、属性名(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文本、多语言、格式化文本

注意事项

  1. FName
    • 避免存储动态内容(如玩家输入的名称),因其内容不可变。
    • 大小写转换可能导致哈希冲突(如FName(TEXT("NAME"))FName(TEXT("name"))视为相同)。
    • 虽然本身不区分大小写,但转换类型后还是区分的(FName(TEXT("NAME")).ToString()FName(TEXT("name")).ToString()并不相等)
  2. FString
    • 频繁拼接操作建议使用FString::Reserve()预分配内存。
    • 避免在性能关键代码中过度使用(如每帧执行的逻辑)。
    • FString 虽然大小写敏感,但使用 == 比较时是不区分大小写的
  3. FText
    • 必须通过本地化工具(如Localization Dashboard)管理多语言文本。
    • 直接使用字符串字面量时,优先用LOCTEXT而非FText::FromString,以支持本地化。