UE4字符串系统FName

发布时间 2023-05-31 16:16:51作者: tomato-haha

# FName

此文为FName (opens new window)的原创翻译,本文内容版权归原文所有,仅供学习,如需转载望注本文地址,翻译不易,谢谢理解。

当你在内容浏览器中命名一个新的资产时,改变一个动态材质实例的参数,或者获取SkeletalMesh上的一个骨骼,你在使用FNames。FNames提供了一个使用字符串的轻量系统,在这里一个给定的字符在数据表中只存储一次,即使该 字符被重用。FNames是大小写敏感的,它们是不可变的而且不能被操作,这样的存储系统和其静态特性意味着它能通过键被很快地查找到并获取值,FName子系统的另外一个特性是使用哈希表来将string更快地转换为FName。

FName不区分大小写,和索引组合在一块被存储在一张表中,这个表里包含了不重复的字符串和这些字符串实例有关的一串数字。

# 创建FNames

FName TestHUDName = FName(TEXT("ThisIsMyTestFName"));
1

# 转换

FNames只能被转换为FStrings和FText,只能由FStrings转换过来。

# FName转换成其他

From To 例子
FName FString TestHUDString = TestHUDName.ToString();
FName FText TestHUDText = FText::FromName(TestHUDName);
  • FName->FText,这个转换过程有时候是合法的,但是FName的内容并不能受益于FText的自动本地化。

# 其他转换成FName

From To 例子
FString FName TestHUDName = FName(*TestHUDString);
FText FName 没有直接从FText转换成FName的方法,可以转换成FString再转换成FName。
  • FString->FName,这个转换过程有点危险,因为FName是不区分大小写的,所以这个转换过程是由损耗的。
  • FText->FString->FName,这个转换过程有点危险,因为FName是不区分大小写的,所以这个转换过程是由损耗的。

注意,在做这些转换的时候,请注意它们可能包含对你创建的FName类型无效的字符。在NameTypes.h文件中的INVALID_NAME_CHARACTERS宏定义哪些字符对于FName是有效地,FName中的几个函数(比如IsValidObjectName())可以作为特殊使用场景来检查FNames的有效性。

# 比较

==操作符可以用来比较两个FNames,它会返回true或false。这个操作做的不是字符串自身的比较,它比较的是两个字符串索引的值,这能节省下大量CPU性能。

也可以用FName::Compare来比较两个FNames,如果当前FName小于被比较的FName的,那么它返回值会小于0,如果当前FName等于其他FName,那么它返回值等于0,如果当前FName大于其他FName,返回值会大于0。

CompareFloat = TestFName.Compare(OtherFName);
1

# 使用FNames

使用FName是十分直接的。现在假如我们想要从Actor上的SkeletalMeshComponent获取下名字为pelvis的骨骼,下面C++代码展示了如何将即时构建的FName传入GetBoneRotation()。

FRotator rotPelvis = Mesh->MeshGetInstance(this))->GetBoneRotation(FName(TEXT("pelvis")));
1

这创建了一个FName然后传入了GetBoneRotation(),然后这个函数会返回相应骨骼的FRotator。这个骨骼的名字在加载包的时候也被加载进FName的表中,所以FName的构建器在hash表中找到了这个骨骼了名字,不用再分配空间。

# 查找名称表

如果你想知道一个FName是否在名称表中,但你不想自动添加它,你可以给FName构建器提供一个不同的搜索类型。

if( FName(TEXT("pelvis"), FNAME_Find) != NAME_None )
{
    // Do something
}
1
2
3
4

如果这个名字不存在于名称表,FName的索引会被设为NAME_None,注意我们不是检查一个正常字符串的指针是否为空。